-
Notifications
You must be signed in to change notification settings - Fork 54
React Component Lifecycle Methods
React Class Components come with a suite of Lifecycle methods to give us some control over the lifecycle of a component instance.
In one lifecycle, in the same way that humans are born once, develop several times through life and pass on once, React Components are 'mounted' once, can be 'updated' multiple times and 'unmounted' once. We don't know if humans can have more than one lifecycle but React Components certainly can!
NB: functional components can not access these methods.
Here is a fantastic, simple diagram of all the lifecycle methods. Note what is added/taken away when clicking on 'Show less common lifecycles'. As well as the 3 stages of mounting, updating and unmounting, we are also aware of a 2nd dimension of phases - render, pre-commit and commit. Reading the official React documentation on these methods is highly encouraged but here is a brief overview of the methods, starting with the most common ones.
The constructor acts just like a regular class syntax constructor. Remember to call super()
if you want to access this
during the constructor.
Usually used to define state, refs and bind functions. You may not often find that you need to use the constructor since we can now define state as a class property outside of a constructor function.
constructor() {
super()
this.state = {
msgCount: 0,
darkMode: true
}
this.chatThreadRef = React.createRef()
}
The only explicitly required lifecycle method. Without it, our component doesn't know what to put on the DOM!
render(){
return (<p>Render me!</p>)
}
This is the first point at which you can trigger side effects. A great place to make initial API calls and start intervals or timers.
Only runs once, after component has finished mounting.
componentDidMount(){ this.commenceTheStream(); }
commenceTheStream = () => {
this.fetchAMeme();
const interval = setInterval(this.fetchAMeme, 2000);
this.setState({ interval })
}
Like cDM but happens after each re-render. You can trigger side-effects and use setState
here but be mindful that this method will run after every update (unless intercepted by shouldComponentUpdate
) so you may end up in a never ending cycle of re-renders if you are not careful! If getSnapshotBeforeUpdate
returned data, it is available here as the third parameter.
Receives prevProps
, prevState
and optional snapshot
, can access this.props
and this.state
.
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot) {
const chatThreadRef = this.chatThreadRef.current;
chatThreadRef.scrollTop = chatThreadRef.scrollHeight - snapshot;
}
}
This is for last-minute tidying up before unmounting. Clear any intervals or timers you had setup here. Only runs once, just before component unmounts.
componentWillUnmount(){ this.stopTheMemes(); }
stopTheMemes = () => clearInterval(this.state.interval);
Not commonly used - there are usually better ways to do whatever it was you were thinking of doing here! static
method.
Receives props
and state
, should return a new object that will be the new state, or return null
for no changes to be made.
static getDerivedStateFromProps(props, state){
if(props.messages.length > state.msgCount &&
props.messages[props.messages.length-1].body === 'switch theme' ){
return { darkMode: !state.darkMode, msgCount: props.messages.length }
}
return null;
}
This runs by default with a return value of true
. To intercept and make a calculated decision on whether the component should proceed with the update, we can explicitly define shouldComponentUpdate
. Receives nextProps
and nextState
, can access this.props
and this.state
. Should return boolean value.
shouldComponentUpdate(nextProps, nextState){
return (this.props.messages.length !== nextProps.messages.length);
}
Another fairly uncommon one. It allows us to take a 'snapshot' of any data so we can pass it as componontDidUpdate
's 3rd parameter, where we can react to the data received.
Receives prevProps
and prevState
, can access this.props
and this.state
.
getSnapshotBeforeUpdate(prevProps, prevState) {
if (this.props.messages.length > prevProps.messages.length) {
const chatThreadRef = this.chatThreadRef.current;
return chatThreadRef.scrollHeight - chatThreadRef.scrollTop;
}
return null;
}
For more information on our transformative coding education, visit us at https://www.lafosseacademy.com/