1
  • when changing state of a component and then changing url, the preact component does not unmount
  • problem is specific to IE and safari
  • when using the "go back" function of the browser, componentDidMount does not trigger and state is not set to initial value

Here is an example, you can run locally to get a better understanding.

 <html>
        <head>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/preact/8.4.2/preact.js"></script>
            <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>  
        </head>
        <body>
            <div id="app"></div>
            <script type="text/babel">
              const React = preact;
              class Foo extends React.Component {
                state = {
                  loading: false
                }

                componentDidMount() {
                  console.log('mounted');
                }

                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>;
                }
              }

              React.render(
                <Foo />,
                document.getElementById('app')
              );
            </script>
        </body>
    </html>
  • click the button
  • wait for redirect
  • go back
  • page still shows: "loading..."

What would be the best solution to reset the state when going back?

pmkro
  • 2,542
  • 2
  • 17
  • 25
oshell
  • 8,923
  • 1
  • 29
  • 47

1 Answers1

1

I found out this problem is related to safari back-forward cache. A solution for the described problem would be to listen to pageshow event and than check if the page loaded is cached or not.

componentDidMount() {
  window.addEventListener('pageshow', (event) => {
    // fix for safari cached page
    if (event.persisted) {
      this.setState({
        isLoading: false
      });
    }
  });
}

Edit: the pageshow event is only triggered one time and this is a known webkit bug. To avoid this you actually have to use window.location.reload() to reset everything. This way the event will trigger again the next time.

oshell
  • 8,923
  • 1
  • 29
  • 47