Every component in react goes through a series of lifecycle events very similar to that of human lifecycle: cycle of birth, growth and death.
In react we call them :
Mounting: Birth of the component
Updating: Growth of the component
Unmounting: Death of the component
Lifecycle methods:
render()
- As the name suggests if you want to render elements in the DOM, we could use the
render()
method. render()
mounts the component onto the DOM and renders them to the UI.render()
is invoked whenever there is a variation in the component’s state(this.state)
or props(this.props)
.- React requires
render()
to be pure i.e with no side-effects which means you cannot update component's state within render (no using setState). render()
could return strings, numbers, arrays, fragments, Booleans or null value, portal, or React elements.render()
will not be invoked if shouldComponentUpdate() returns false.
Examples://return string
render() {return "Hello!!"}
//return null, doesnt render anything
render() {return null}
//return fragments
render() {return (<React.Fragment><div>Hello</div></React.Fragment>)}
//return arrays
render() {return [<div key="1">Hello</div>, <div key="2">World</div>];}
//return Components
render() {return <div>Hello {this.props.name}</div>}
- As the name suggests if you want to render elements in the DOM, we could use the
componentDidMount()
👶- After the
render()
method, when the component has been inserted into the DOM,componentDidMount()
is called. - Here one can setup any subscriptions or send any network requests.
- Also one could update state using
setState
insidecomponentDidMount()
which would further trigger a render. - However, the problem here is that it may cause performance issues so it is advisable to this pattern with cation. Good practice includes you assigning value to the initial state.
For example: Consider that you setState of a component initailly in the first render and the thing to which you are going to setState is in the localStorage.
So instead of doing something like this which could again trigger a render because of setState:componentDidMount({this.setState(JSON.parse(localStorage.getItem("someData")))}
. - You could give your state an initial value:
state=JSON.parse(localStorage.getItem("someData"))
- This pattern is mostly used when you need to measusre a DOM node before rendering something that depends upon its size. Example: tooltips, modals or incases where you need to measure window dimensions
In functional React it is similar to
React.useEffect
with an empty dependency arrayReact.useEffect(() => { // Your code here }, [])
Example:
- After the
componentDidUpdate()
💅- It runs anytime there are changes to state or props to this component
For example: If you type something on the input field (i.e. if you update the component),componentDidUpdate()
runs and update is console logged into the console. - In functional React it is similar to
React.useEffect
with an no dependency arrayReact.useEffect(() => { // Your code here })
componentDidUpdate()
also receivesprevState
andprevProps
as parameters and also the newly changed state or props.- In functional React it is similar to
React.useEffect
with some dependency arrayReact.useEffect(() => { // Your code here },[dependencies])
- This is very important as you could setState by wrapping a condition to check for state or prop changes from previous state which can save from an infinite loop to occur.
- If you directly use
setState
within this function, it will trigger render andcomponentDidUpdate
infinitely
For example: Here if you comment out the check for prevState and click on the + buttoncomponentDidUpdate()
will trigger thesetState
then therender()
and again thecomponentDidUpdate()
and so on.
- It runs anytime there are changes to state or props to this component
4.componentWillUnmount()
🪦
componentWillUnmount()
is called just before the component is unmounted and destroyed. If there are any cleanup actions that you would need to do, like canceling network requests, invalidating timers, or cleaning up unwanted subscriptions that were created in thecomponentDidMount()
method.- In functional React it is similar to
React.useEffect
with a return functionReact.useEffect(() => { // Your code here return()=>{//cleanup code} },[])
- One cannot modify the state in
componentWillUnmount()
method For example: Here in this code if you comment the
componentWillUnmount()
and try to toggle the windowTraker and unmount it from the screen and then resize the window, you will get an error saying
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
This is because the imperative mannual addeventListner is still listning for the resize event which then calls watchwidth which tries to setState to the component that is not mounted anymoreimport React from "react"; export default class App extends React.Component { state = { show: true, windowWidth: window.innerWidth }; watchWidth = () => { this.setState({ windowWidth: window.innerWidth }); }; componentDidMount() { window.addEventListener("resize", this.watchWidth); } componentWillUnmount() { window.removeEventListener("resize", this.watchWidth); } render() { return ( <div> <button onClick={() => this.setState((prevState) => ({ show: !prevState.show })) } > Toggle WindowTracker </button> {this.state.show && <h1>Window width: {this.state.windowWidth}px</h1>} </div> ); } }
These are most commonly used lifecycle methods. There are more methods which you can find them here.
Happy coding 🚀