Day 2 was a continuation of our understanding of the useEffect
hook. Some of concepts mentioned were concepts I “felt” while getting my hands dirty. The workshop was a conducive environment to make these concepts known to me more.
- Some keywords, libraries or links of interest:
usehooks-ts
eslint-plugin-react-hooks
- React lifecycle diagrams
- The dependency array in
useEffect
does diffs by identity.- For primitives, we diff by value.
- For objects, we diff by memory location.
- We need to be careful when placing non-primitives into the dependency array. We risk getting into infinite loops.
- Ways to get into an infinite loop:
- Placing
setMyState
into the return (render) value unconditionally. This means we runsetMyState
, changemyState
and trigger re-renders.
- Placing
useEffect
can offer the functionalities of bothcomponentDidMount
andcomponentDidUpdate
by configuring the dependency array.useEffect
with a non-vacant dependency array is similar to acomponentDidUpdate
with an if statement checking the state of the dependency.
- We cannot run
setMyState
on an unmounted component. There can be race conditions where the component can either be mounted or unmounted when we runuseEffect
.
useEffect
can return a cleanup function in the form: return () => {}; (docs)
- There is no built-in API to check if a component is mounted.
useEffect(() => {
// Do API call with courseSlug with .then(course => setCourse(course))
}, [courseSlug]);
// This can lead to race conditions and memory leak.
// If we click rapidly, only the last API call survives.
- So, do it yourself. These are equivalent:
// Inside a functional component
useEffect(() => {
let mounted = true;
if (mounted) {
// Set state in API callback
}
return () => {
mounted = false;
};
}, [courseSlug]);
// Class component
class YourComp {
let mounted = true;
// ...
componentWillUnmount() {
mounted = false;
}
}
// Read: https://reacttraining.com/blog/isMounted-tricks-are-code-smell
const mountedRef = useRef(true); // synonomous with a mutable state that does not cause re-render
- Can you have more than one effect per component? Yes. There is no need to merge effects into one big
useEffect
.
- Do you need cleanups? Not always.
- Side effects should run after render phases Which render phases? Not all. We don’t want to run side effects on the server (SSR). Running side effects on render phase = any amount of bugs can come (legacy docs).
TBC!