Dispatching with useEffect cleanup function
Closed this issue · 2 comments
I am using vegemite with Rxdb
In a React component:
useEffect(() => {
store.listen(setState);
store.dispatch('loadData'); // load data and subscribe a function for state update
return () => { // cleanup function
store.dispatch('onUnloadData'); // unsubscribe methods
};
}, []);
store.on('onUnloadData', (state) => { subs.forEach((sub) => sub.unsubscribe()); });
When calling store.dispatch('onUnloadData');
Occurs an error: "Can't perform a React state update on an unmounted component."
Because all dispatch functions performs state update. So store.dispatch('onUnloadData');
performs new state update.
We need a store.slientDispatch('onUnloadData') like function.
Currently I am using a solution. Using store.destroy() function rather than dispatching onUnloadData like event.
store['destroy'] = () => { subs.forEach((sub) => sub.unsubscribe()); };
May be the that thought:
// only event dispatching so do not perform state update
store.manuelDispatch(event)
// or optionally state update without klona library
store.manuelDispatch(event, (state)=> {
const newState = {...state};
// ... some state update on newState
return newState;
})
if this is ok i can send a pull request.
Hi there,
It might help to see more code, but your useEffect
isn't cleaning itself up and that's your problem. I'll direct you to this example, especially if you haven't seen it before.
You'll notice that I return the store.listen(...)
directly. This tells P/React that it needs to call the unsubscriber function that store.listen
returned.
In your example, you never unsubscribe, and so that's why you get the error. When you think the store is done listening & calling setState
, it's not.
How about trying this instead:
useEffect(() => {
let unsub = store.listen(setState);
store.dispatch('loadData');
return () => {
store.dispatch('onUnloadData').then(unsub); // <~ unsubscribe
};
});