React Component Lifecycle Hooks Cheatsheet
Bunlong
Posted on February 2, 2020
useState
, useEffect
, useRef
and React.memo
are the hooks and the higher order component that allow you to replace React class component lifecycle methods.
useState
Use: to manage a component’s local state.
Purpose: to replace the need for this.state and constructor.
useEffect
Use: to manage side effects (Ex. an API request, tracking analytics, interacting with DOM not contained inside your React app, etc).
Purpose: to replace the need for lifecycle methods (React Component Lifecycle Methods Cheatsheet).
useRef
Use: to provide the way to access DOM nodes or HTML elements created in the render method.
Purpose: to helps the useEffect
to replaces the need for componentDidUpdate
.
memo
Use: to manage a component’s re-rendering.
Purpose: to replace the need for shouldComponentUpdate
.
Explanation with Words and Code
const {useEffect, useState, useRef, memo} = React;
const ReactLifecycleHooks = (props) => {
// Commonly Used Hooks
// Purpose: Initialize state, read and update state variable.
// The useState hook allows you to read and update a state variable.
// The usetState function returns an array containing the current value and the function to
// update the value.
const [desc, setDesc] = useState('user');
const [prevCount, setPrevCount] = useState(null);
// The mounted variable of useRef here is used to check the component is rendered.
const mounted = useRef();
console.log('render');
// The useEffect hook takes 2 arguments, a function containing a side effect action and an array.
// The array contains the variable(s) that you want to track.
// When a value in the array changes, the side effect function is executed.
// The empty array is passed to useEffect as its second argument
// in the purpose of replacing the useEffect with componentDidMount & componentWillUnmount.
useEffect(() => {
console.log('componentDidMount');
// Lifecycle: Mount immediately after render.
// Purpose: Initialize state that requires DOM nodes, Network requests and side effects.
return () => {
console.log('componentWillUnmount');
// Lifecycle: Unmount.
// Purpost: Clean up things such as event handlers, cancel network request, etc.
}
}, []);
// The array containing props.count is passed to useEffect as its second argument
// in the purpose of replacing the useEffect with componentDidUpdate.
// The useEffect is tracking the value of props.count, and when it sees a change, the side effect
// function is executed.
// When the side effect function executes, the logic of checking componentDidUpdate is executed.
useEffect(() => {
if (!mounted.current) {
mounted.current = true;
} else {
console.log('componentDidUpdate');
// Lifecycle: Update immediately after render.
// Purpose: Operate on updated DOM or handle network requests.
}
}, [props.count]);
// The logic of calling function getDerivedStateFromProps.
if (prevCount !== props.count) {
setDesc(ReactLifecycleHooksOptimization.getDerivedStateFromProps(props, desc));
setPrevCount(props.count);
}
// Required
// Code to display the component.
return (
<>
{props.count} {desc}
</>
)
}
// Return true if you don't want it to rerender, return false if you want it to render.
const shouldComponentUpdate = (prevProps, nextProps) => {
console.log('shouldComponentUpdate');
// Lifecycle: Update immediately before render.
// Purpose: Allows developer to prevent rendering.
return nextProps.count === prevProps.count;
};
// The memo higher order component allows you to replace the need for shouldComponentUpdate.
// The memo higher order component takes 2 arguments, a component and a comparison function of
// prevProps and nextProps.
const ReactLifecycleHooksOptimization = memo(ReactLifecycleHooks, shouldComponentUpdate);
// Rarely Used Lifecycle
// The getDerivedStateFromProps function here is created for the purpose of
// using getDerivedStateFromProps in hooks.
ReactLifecycleHooksOptimization.getDerivedStateFromProps = (nextProps, prevState) => {
console.log(`getDerivedStateFromProps
nextProps.count=${nextProps.count}
prevState=${prevState}`);
// Lifecycle: Mount and update immediately before render.
// Purpose: When your state depends on props (should be avoided).
if (nextProps.count === 0 || nextProps.count > 1) {
return 'users';
}
return 'user';
}
const Nothing = () => 'Nothing';
const App = () => {
const [component, setComponent] = useState(1);
const [count, setCount] = useState(1);
const Component = component > 0 ? ReactLifecycleHooksOptimization : Nothing;
return (
<>
<button onClick={() => (console.clear(), setComponent(component > 0 ? 0 : 1))}>Mount/Unmount</button>
<button onClick={() => (console.clear(), setCount(count + 1))}>Update value</button>
<Component count={count} />
</>
);
};
ReactDOM.render(<App />, document.getElementById('app'));
Live demo is available on CodePen.
Note
According to the React docs, getSnapshotBeforeUpdate
, componentDidCatch
and getDerivedStateFromError
, there are no Hook equivalents for these methods yet.
References
Posted on February 2, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 6, 2024