Are you a React dev? 🙌
Are you doing it properly?
Do you know React? 🤔
** wow, big scare, such doubts **
Don't worry! React is still React and you probably used it well already
But, if you NEVER used React before
👨💻 build dynamic web apps
⚒️ develop reusable components
💪 brag about the fact that you don't use Angular
🔥 use the latest javascript features
and many other things...
What before was done with classes
Now we can do functional!
And manage our state with hooks
Hooks like useState trigger a rerender of the component every time the state changes
To do this, React uses something called virtual DOM along with a diffing algorithm that serves for what is the main mechanism of sync between UI and states
There are quite a few hooks that we can use to play around with React and build our apps
and many more...
and yes, hooks are functions and a function is a hook if it starts with the word use
we can also make our own hooks, and the same rules apply:
- must begin with use
- must use at least one react hook
Now that we are React professionals
Let's dive right into useEffect
useEffect has:
A badly configured useEffect can lead to weird things
Our minds are still a little bit intertwined with the previous class way of dealing with state and life cycle of the components
We have to remember that useEffect is for keeping in sync the UI with some external state that cannot be controlled directly by React's first rendering
useEffect runs only after render
The ref.current property would result to be undefined outside of a useEffect because the DOM node has yet to be mounted
So what should we do? We should rewire our thinking in React.
Unlearn, you must.
Classes come with life cycles and state
Functional Components are kind of stateless
but they can become stateful thanks to hooks
and hooks are probably easier to read and write than classes are
Rules for hooks are of the uttermost importance
Breaking out of React will only result in unexpected behavior from your app
You can install ESLint to make sure you don't go against them
So, let's finally start
React 18 is out a few months now and everyone is having problems with it
Strict Mode in React comes out of the box if you start your app with a CLI utility like CRA or Vite
What people tend to forget is the fact that Strict Mode can be opted-out at any time and is development only
You don't have it in your production app after build
So why is everyone crying about it?
Because useEffect now double renders the component. Better yet, useEffect mounts, unmounts and remounts the component
It does so on every component mount
It's not a bug
it's intentional
The application is actually helping you find weird component bugs before they get into production, which is actually a good thing
If your component behaves in unexpected ways
only because of this second rerender
We should stop thinking about Functional components as if they were class components
We shouldn't be asking
"how can I run this only once?"
instead
"why is it not working properly on remount?"
Let's remember
And yet, you want to stop React from doing that in Development, for no particular reason
There are solutions
Solution 1, useRef
Solution 2, delete StrictMode
The solutions proposed are just escape hatches
So let's go back a bit and ask ourselves, again
Why are we escaping this helping mechanism?
"But I don't want to fetch twice!"
Fair enough. Why are you doing it in useEffect than?
"That's where it's supposed to be done!"
Also good point. Why are you building your own fetch calls tho?
React is mainly a UI library
Want to fetch inside useEffect, only on mount, only once?
Build your own caching mechanism
Build your own error handling and loading
Build your own cancelling signal (AbortController)
That's a lot of stuff to build, so why would you?
〰️ React SWR
⚛️ RTK Query
This solutions come with what you need out of the box, no need to reinvent anything and they are production ready and open source
Will this stop the double rendering with useEffect?
No, it will not, but, you don't need that
HTTP requests will be cached and canceled by those solutions, hence you will have no problems with rerendering components
fun fact
page changes by users trigger the same mechanism so you are actually virtualizing real world usages with StrictMode
and yet, you want to build your own fetching mechanism
There it is, a bad copy of React Query
just use react-query
Nice resources to check out online!
🔗 Fetch API and AbortController
Nice resources to check out online! part 2
🔗 How to fetch data with React Hooks
🔗 React useEffect double rendering fix and why you should stop crying about it