Stale state seems to be written to store when using a recursive object structure
chrisandrewca opened this issue · 1 comments
Hello! Thanks for sharing unistore. Its a nice way to break into the redux-like world.
I'm having a problem where new state is being rendered and logs say its written to the store, yet when checking local storage mostly old state is there.
I have an object like
{
customization: {
...fields,
options: [{
id,
fields,
menuState,
options: [{...}],
parent
}]
}
}
When I update options. I copy the array, copy each element, and copy its children, and so on. The code looks like:
const toJsonable = (optionTree) => {
const { items } = optionTree;
const options = [];
for (const ref of items) {
const option = { ...ref };
/* mutations on copy */
if (option.options.length) {
option.options = toJsonable({ items: option.options });
}
/* deletes */
options.push(option);
}
return options;
};
I'm using unissist to persist to local storage. When I fire off the work with useEffect the component renders the updated state and the logs inside subscribe read that its been persisted to local storage. Then when I check local storage the old state is there.
I read the equality comparison in unistore and when logging here mapped holds the correct state...
let update = () => {
let mapped = mapStateToProps(store ? store.getState() : {}, props);
for (let i in mapped) if (mapped[i]!==state[i]) {
state = mapped;
return this.setState({});
}
for (let i in state) if (!(i in mapped)) {
state = mapped;
return this.setState({});
}
};
When I don't use the nested options array; and submit a flat array [...options] the new state is found in storage. Then when using a nested options array [{option: { options: [...] }] the old state is found.
It really sounds like a copy issue.... but with all the logs saying all good all the way down, I'm not sure what to do. Do you think I'm missing a copy? Or maybe some type of async issue? I tried indexdb and had even worse results...
Figured it out! Of course it was nothing to do with unistore :D
Issues I had:
- App.js has style routes, components wrapped in an Auth HoC would create additional stores in memory. Moved create store to the App component.
- Updated App component to be a class to use the lifecycle methods for sub/unsub
- Cleaned up a lot of async is loading / is authenticated mish mash while doing this
Thanks again for the lib.
Cheers,
Chris