dai-shi / react-hooks-global-state

[NOT MAINTAINED] Simple global state for React with Hooks API without Context API
https://www.npmjs.com/package/react-hooks-global-state
MIT License
1.1k stars 62 forks source link

Race condition is back on setState #19

Closed vans163 closed 5 years ago

vans163 commented 5 years ago

So I started using a 3rd party api that loads side by side the initial render. When setGlobalState is called, the first render does not notice the state was changed.

A second forced render a second later, picks up on the change. Something is making observableBits crap out, and I am not sure I could easily replicate this.

Is there anywhere in the code here, if setState gets called, it wont render upon initial render.

EDIT: I traced this bug/feature, hoping its a bug. If the initialState does not define the field, during first render it gets skipped over.

Broken code

initialState = {
}

const [s_user] = useGlobalState("user");

function asynccallback() {
    setGlobalState("user", ()=> {return {email: "bob@test.com"}})
}

Working code

initialState = {
    user: {}
}

const [s_user] = useGlobalState("user");

function asynccallback() {
    setGlobalState("user", ()=> {return {email: "bob@test.com"}})
}
dai-shi commented 5 years ago

I traced this bug/feature, hoping its a bug. If the initialState does not define the field, during first render it gets skipped over.

Oh, yes. Maybe, it isn't clear enough in README. But, that's the base idea of this library. All fields be must be provided in createGlobalState and even in createStore. It's quite different from Redux, and it's more like multiple contexts. Ref: my recent blog

In TypeScript, it will clearly show a compile error, it should probably show a runtime error too for JavaScript.

dai-shi commented 5 years ago

@vans163

const initialState = {
    user: null,
};

It can be just null. Hope it work for your use case.

vans163 commented 5 years ago

can be closed, thanks.