question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React.StrictMode causes async action listeners to not be cleaned up properly

See original GitHub issue

Hi, 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]();
        }
    }
}

Screenshot_3

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:

Screenshot_2

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:open
  • Created 3 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
a-tonchevcommented, Sep 21, 2020

@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…

0reactions
schummarcommented, Dec 10, 2020

Right, late to the party. 😄 I might have a look at that too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Strict Mode - React
StrictMode is a tool for highlighting potential problems in an application. Like Fragment , StrictMode does not render any visible UI.
Read more >
How to use async function in useEffect? - DEV Community ‍ ‍
In React we all must have used useEffect hook which runs after performing DOM updates and helps us to perform some operation after...
Read more >
React 18 strict mode causing component to render twice
React StrictMode calls all Effects twice to make sure their cleanup/unmount handlers work as intended. You may need to change your effects ...
Read more >
Redux Essentials, Part 8: RTK Query Advanced Patterns
In Part 7: RTK Query Basics, we saw how to set up and use the RTK Query API to handle data fetching and...
Read more >
Node.js v19.3.0 Documentation
Passing arguments and this to listeners; Asynchronous vs. synchronous ... eliminating the need to track and clean up as many individual ArrayBuffer objects....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found