Lifecycle Methods
Class-based components have the following five lifecycle methods:
- componentWillMount
- componentDidMount
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
As of version 2.1.0, you can also use lifecycle hooks with functional components. Check the documentation to learn more.
Lifecycle methods are hooks that let you implement maintenance, register or remove events, and other clean based on the status of a component from when it is created and injected into the DOM, when it is updated and when it is removed from the DOM.
componentWillMount
is executed before the component is created and inserted into the DOM. As such, it will always fire, whether the mount was successful or not. If you need to access the DOM, set up an event, or make a network request for remote resources, use the componentDidMount
hook.
This lifecycle hook receives a callback named done
. You need to call this after doing whatever you need to do
before the component is updates. If you fail to call done()
, the update will not complete. Mounting is triggered by a component's state, so this is not the place to get data to set on a component. Get the data first and then set the component's state.
componentWillMount(done) {
// Do whatever you need to here...
// Delay mounting by 3 seconds
setTimeout(() => {
// Don't forget to call done:
done()
}, 3000)
}
componentDidMount
is executed after the component is inserted into the DOM. This is the place to set up events, access the child nodes of the component, or make a request for remote resources over the network. The callback gets passed a reference to the component instance as its argument. Using this, you can use this.element
to access the component instance DOM tree.
componentDidMount() {
// Access the component instance root element:
this.element.addEventListener('click', this)
this.input = this.element.querySelector('input')
}
componentWillUpdate
is executed right before the component is updated. It will not execute if the component is not yet mounted. Because this is async, the component will probably update before this finishes executing. It's best to instead use componentDidUpdate
for reliability. Otherwise, do whatever you need to do before the update and use a promise to update it.
componentWillUpdate
will execute when Composi tries to update a component. If a component is updated with the same data as previously, no update will occur and this will not execute. You can access this.element
, this.props
and this.state
from within the componentWillUpdate
callback. This lifecycle hook receives a callback named done
. You need to call this after doing whatever you need to do before the component
is updates. If you fail to call done()
, the update will not complete. Here is how to use it. Failing to call done()
in componentDidUpdate
means that the component will be out of sync with its state.
In the following example we delay the update of the component for 3 seconds:
import { h, Component } from 'composi'
class Title extends Component {
render(data) {
return (
<nav>
<h1>
</h1>
</nav>
)
}
// Pass in the done callback to complete the update:
componentWillUpdate(done) {
console.log('Getting ready to update!')
// Do whatever you need to do before updating...
// Delay update for 3 seconds:
setTimeout(() => {
console.log('We are now updating!')
// Don't forget to call done!
done()
}, 3000)
}
}
componentDidUpdate
is executed immediately after the component is updated. If a component is updated with the same data as previously, no update will occur and this will not execute. You can use this lifecycle hook to examine the component instance element, props and state like with componentWillUpdate
. Be aware that this.props
never changes as it is the value assigned when the component was instantiated.
componentWillUnmount
is executed before a component is unmounted with its unmounted method. This receives a callback named done
. You need to call this after doing whatever you need to do before the component is unmounted. If you fail to call done()
, unmounting will not complete. Here is how to use it. Notice how we delay the removal of the component for 5 seconds:
import { h, Component } from 'composi'
class Title extends Component {
render(data) {
return (
<nav>
<h1>
</h1>
</nav>
)
}
// Pass in the done callback to complete the unmounting:
componentWillUnmount(done) {
console.log('Getting ready to unmount!')
// Do whatever you need to do before unmounting...
// Delay unmount for 5 seconds:
setTimeout(() => {
console.log('We are now unmounting!')
// Don't forget to call done!
done()
}, 5000)
}
}
Notice: If you do not call the done
callback as in the above example, the component will never unmount.
Difference between Will and Did
The three lifecycle hooks with Will
in their names allow you to delay they action until you are ready. This is done with the done
callback. If you are using componentWillMount
, componentWillUpdate
or componentWillUnmount
you have to pass them the done callback:
componentWillMount(done) {
// Do whatever you need to here...
// Let the mount happen:
done()
}
componentWillUpdate(done) {
// Do whatever you need to here...
// Let the update happen:
done()
}
componentWillUnmount(done) {
// Do whatever you need to here...
// Let the unmount happen:
done()
}
In contrast, componentDidMount
and componentDidUpdate
execute immediately.
Order of Execution
The first time a component is rendered, componentWillMount
and componentDidMount
will be executed. componentWillUpdate
and componentWillUpdate
will not be executed at this time. After the component is created, each render will fire componentWillUpdate
and componentDidUpdate
. So, if you want to do something when the component is initially created and after it updates, you would need to do this:
class List extends Component {
//... setup here.
componentDidMount() {
// Do stuff right after the component mounts.
// This will run only once.
}
componentDidUpdate() {
// Do stuff every time component is updated.
// This will start with the first update after mounting.
}
}
Accessing the Component Instance in Lifecycle Methods
When we create a new component by extending the Component class, we can access component properties directly through the `this` keyword. This is so because we define the lifecycle methods as class methods. Notice how we do this in the example below.
See the Pen Composi lifecycle-2 by Robert Biggs (@rbiggs) on CodePen.