Coder Social home page Coder Social logo

Component that changes a sub-property of its own state object by async method re-renders the whole component in an infinite loop about arrow-js HOT 6 OPEN

Clonkex avatar Clonkex commented on June 5, 2024
Component that changes a sub-property of its own state object by async method re-renders the whole component in an infinite loop

from arrow-js.

Comments (6)

Aidenir avatar Aidenir commented on June 5, 2024 2

Alright, thanks for the reply @Clonkex :) . I did find a super janky workaround I think, where I changed the type of the value I keep in the reactive state to a string instead of an array: https://jsfiddle.net/09Lwopqy/

    function getLoginComponent() {
        const state = reactive({
            pageDatas: "[]",
        });
        setTimeout(async () => {
        		state.pageDatas = JSON.stringify(JSON.parse(state.pageDatas).push(Date.now()))
        }, 500);

        return html`<div>bob</div>`;
    }

From limited testing this at least solved my issue for now, and while it's definitely not a good solution, it let me keep working on the other problems in my app until hopefully a better solution comes along :P

from arrow-js.

Aidenir avatar Aidenir commented on June 5, 2024

I've run into the same issue just now. Did you ever found a solution/workaround @Clonkex ?

from arrow-js.

Clonkex avatar Clonkex commented on June 5, 2024

@Aidenir Unfortunately my "solution" was to switch to Preact + HTM (which is relatively easy to achieve even with an existing ArrowJS codebase because the ArrowJS and HTM syntax is similar - it's also still fully clientside, no build step necessary). It's not quite as elegant as ArrowJS in some ways (in particular, it took me a while to get my head around state handling - having to set an entirely new copy of the object when anything changes feels jank, but also potentially simpler and more reliable) but in other ways it's simpler and has the significant benefit of being battle-tested. If you make the same switch, just know that when you're trying to understand some Preact feature, search for React first because Preact is basically just a reimplementation of React.

So yeah, I was unable to work around this problem and it was enough to make me suffer the pain of learning Preact instead.

from arrow-js.

jfftck avatar jfftck commented on June 5, 2024

Alright, thanks for the reply @Clonkex :) . I did find a super janky workaround I think, where I changed the type of the value I keep in the reactive state to a string instead of an array: https://jsfiddle.net/09Lwopqy/

    function getLoginComponent() {
        const state = reactive({
            pageDatas: "[]",
        });
        setTimeout(async () => {
        		state.pageDatas = JSON.stringify(JSON.parse(state.pageDatas).push(Date.now()))
        }, 500);

        return html`<div>bob</div>`;
    }

From limited testing this at least solved my issue for now, and while it's definitely not a good solution, it let me keep working on the other problems in my app until hopefully a better solution comes along :P

There are things wrong with this code and the code above it:

  1. setTimeout doesn't take awaitable functions, remove the async in front of the lambda
  2. You shouldn't set your reactive variable to an object that has one property pageDatas, just use the array directly and it should work fine

Try this: const pageTimestamp = reactive([])
Then you should be able to use it like this: pageTimestamp.push(Date.now())

Also, the naming of the variable to state doesn't describe what you are using it for and pageDatas is also poorly named as it looks to be timestamps. If you need to keep state then you would need to spread the array, as only the object changes are being tracked, so changing the child array directly will never trigger the change event.

Here is how keeping the object would work: state.pageTimestamps = [...state.pageTimestamps, Date.now()]

Please note that using the object will cause additional rerendering if any other properties are attached to that object. That is why I first recommended making the array reactive.

from arrow-js.

Clonkex avatar Clonkex commented on June 5, 2024

@jfftck You're reading too much into my testing code haha. It was cut down from real code and I didn't rename some things.

setTimeout doesn't take awaitable functions, remove the async in front of the lambda

Well in my original code the lambda awaited some stuff, which is why the async is there. I just forgot to remove it. It also makes no difference to setTimeout whether the function is awaitable or not; if the lambda awaits anything it needs to be marked as async.

You shouldn't set your reactive variable to an object that has one property pageDatas, just use the array directly and it should work fine

It's been a while, but I believe I tried this and it made no difference. Or maybe it did make a difference but I couldn't do that because my real state was more complex and had multiple fields.

from arrow-js.

jfftck avatar jfftck commented on June 5, 2024

But your problem of circular loop can be fixed by splitting your state, anything that is for the component directly should be separate from the state for the children. Having it as 1 shared state can cause any changes to rerender both components.

from arrow-js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.