React.StrictMode causes async action listeners to not be cleaned up properly
See original GitHub issueHi, I am using a CRA application, with lazy-loading and react-router-dom.
I am using the createAsyncAction method like this:
const getAllOrders = createAsyncAction(
async () => {
const res = await Connections.postRequest('getAllOrders');
const { orders = [] } = res.data || {};
if (res.ok) {
return successResult(orders);
}
return errorResult([], `Error on getting orders: ${res.errorMessage}`);
},
{
cacheBreakHook: ({ result, timeCached }) => !result.error
&& timeCached + CachingDurations.ALL_ORDERS < DateHelper.getTimestamp(),
},
);
with custom updater inside the component:
const [finished, result, updating] = getAllOrders.useBeckon({ tag: 'allOrders' });
...
const updateOrders = () => {
getAllOrders.run(
{ tag: 'allOrders' },
{
treatAsUpdate: true,
},
);
};
I want to use the cool caching functionality, but I want also to give the user ability to update by himself the data.
So when I open for first time the route and click on the updateOrders function, it works like a charm. But when I open another page and come back to this orders-route, when I click on updateOrders I get this error message:
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
I debug a little bit and figure out, that somehow the event listeners are not really removed when my component is unmounted, that is in the function notifyListeners:
function notifyListeners(key) {
e thi if (clientAsyncCache.listeners.hasOwnProperty(key)) {
for (const watchId of Object.keys(clientAsyncCache.listeners[key])) {
clientAsyncCache.listeners[key][watchId]();
}
}
}
as you can see on the pic, I have 3 listeners.
I tryed to reconstruct here the same issue
https://codesandbox.io/s/pullstate-client-only-example-forked-4707o?file=/src/index.tsx
But here it works fine, and the event listeners are just cleared like they should be:
as you can see on the picture, all the old event listeners are cleared successfully and there is no such issue.
I am a little bit confused. Is there any option to clean all the previous listeners manually in the useEffect?
Thanks
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (7 by maintainers)
Top GitHub Comments
@lostpebble Thanks, yeah well, hopefully they will fix this bug.
There are some recommendations to use the useRef in combination with useEffect:
https://frontarm.com/daishi-kato/use-ref-in-concurrent-mode/#the-good-code
But since I am not an expert in this matter, I don’t know if this could be something useful…
Right, late to the party. 😄 I might have a look at that too.