React 16 triggers componentDidMount()
when going back in Safari, even tho the component never unmounted. How does react know when to mount?
class Foo extends React.Component {
state = {
loading: false
}
componentDidMount() {
// when going back in safari
// triggers in react 16, but not in 15.3 or preact
console.log('mounted');
}
componentWillUnmount() {
// will never trigger
console.log('will unmount');
}
leave() {
this.setState({
loading: true
});
setTimeout(() => {
window.location.href = 'https://github.com/';
}, 2000);
}
render() {
return this.state.loading ? <div>loading...</div> : <button onClick={this.leave.bind(this)}>leave</button>;
}
}
Background
Safari uses bfcache. If you go back it takes the last page from cache.
When using react 15.3 or libraries such as preact, leaving the page will not trigger componentWillUnmount
and going back will not trigger componentDidMount
.
This behaviour causes several issues - for example when you set your page state to loading
before redirecting. If the user goes back, the state is still set to loading and you cannot even reset the state using componentDidMount
, because it never triggers.
There is a solution, by using onpageshow
, but since it only triggers one time, you have to reload the whole page using window.location.reload()
. This is also the reason react cannot rely on this solution.
mounted
message, even after pressing the back button... do you have server side rendering in your setup? that will maybe make a difference – Menstruaterender()
along withcompoDidMount()
– Axenic