4

Why does useEffect Run Twice in React v18.0?

 2 years ago
source link: https://blog.bitsrc.io/react-v18-0-useeffect-bug-why-do-effects-run-twice-39babecede93
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Why does useEffect Run Twice in React v18.0?

Is this a bug in with effects in React 18?

0*8qvE8qz5jwscZ4f4
Photo by Christian Erfurt on Unsplash

After upgrading to React v18, I found a problem with useEffect when I was developing and debugging locally, it wasn’t like I knew it before.

As in the following example:

1*B1dfRqLxL-K3ptbr0NsBOQ.png

Guess what is printed in the console?

1*AtIqMR_GagIMVzzfw0lLCg.png

Yes, you read that right, it prints Call! twice. Specifically, this component is mounted, then unmounted, and then remounted.

This also means that when you fetch data in useEffect, it will be sent twice!

Why is this happening? When I first encountered this problem, I thought it was a bug in my program until I went to the official documentation to see:

It turns out that this is a “new feature” of useEffect. . .

In development mode, if you use the default <React.StrictMode />, then useEffect will behave as above.

The reason given in the documentation is that this approach can make existing problems in our code appear earlier.

For example, the chat room example is given in the documentation:

1*EAYfPhLoAyXIdT34jvv_yw.png

Yes, it is similar to the example I introduced at the beginning. That said, React helps us simulate what happens when a user leaves a chat room and then comes back to it. This allows us to check the program correctly and avoid creating two connections by mistake here.

But what if you want to get data in useEffect? Dan posted this in GitHub’s Issues:

1*qHE23Ts8_AlN805lr6w56A.png

Image from GitHub Issues

Well, if you’ve been a React Query or similar library user before, this might be fine. But if not, then it may take time to learn.

So what was the original intention of adding such a behavior?

The answer is to ensure reusable state. It allows React to add and remove sections of the UI while preserving state. For example, when switching between multiple tabs, keep the state of the previous tab. This can improve the user experience or reduce unnecessary API calls.

Does it feel similar to KeepAlive in Vue? :)

Can it be turned off?

The answer is yes.

Just comment out <React.StrictMode /> at the entry point.

1*Is5OqyKH369-Dif2lAILOg.png

But it also means turning off many of React’s useful strict checks, which isn’t ideal.

Conclusion

Although this feature brings us a strict reminder in development mode, for most people, it increases the learning cost and mental burden.

So what do you think?

References

[1] https://beta-reactjs-org-git-effects-fbopensource.vercel.app/learn/synchronizing-with-effects

[2] https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state

[3] https://github.com/facebook/react/issues/24502


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK