title: Twitter API: Warning: Can’t perform a React state update on an unmounted component
body: <p>I use twitter API with Javascript API for websistes. When I click on anchor tag which should me redirect to /twitter/explore from /twitter I'm redirected to /twitter/explore but immediately back me to /twitter which is Twitter component. I got this error in chrome console:</p>
  
  <pre><code>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. To fix, cancel all subscriptions and 
  asynchronous tasks in the componentWillUnmount method twitter api.
  </code></pre>
  
  <p>I try resolve this problem by add global variable and call setState only when that variable is true and later when component is unmounting I change variable to false. Error does not exist but still the app redirect me back to /twitter. I can't render TwitterExplore component because back me. I'm not sure that this solution with global variable is good idea.</p>
  
  <p>Here is my code below: </p>
  
  <p>Twitter component with mapping /twitter</p>
  
  <pre><code>class Twitter extends React.Component {
  isMountedTwitter = false;
  constructor(props) {
      super(props);
  
      this.state = {
          accessToken: '',
          email: '',
          name: '',
          userID: '',
          pictureUrl: '',
          providerId: '',
          screenName: '',
          tokenSecret: ''
      }
      this.Auth = new AuthService();
  }
  
  componentDidMount() {
      this.isMountedTwitter = true;
  
      this.isMountedTwitter &amp;&amp; window.twttr.widgets.load(document.getElementsByClassName("feed-container")[0]);
  
      let jwtToken = null;
  
      if(this.Auth.getTwitterToken() !== null) {
          jwtToken = this.Auth.getTwitterToken();
      }
      if(this.Auth.getToken() !== null) {
          jwtToken = this.Auth.getToken();
      }
  
      fetch(`/getuserdata/${jwtToken}`, {
          method: 'GET',
          headers: {
            'content-type': 'application/json'
          }
      })
      .then(response =&gt; response.json())
      .then(jsonData =&gt; {
          if(this.isMountedTwitter) {
              this.setState({
                  accessToken: jsonData.accessToken,
                  email: jsonData.email,
                  name: jsonData.name,
                  userID: jsonData.userID,
                  pictureUrl: jsonData.pictureUrl,
                  providerId: jsonData.providerId,
                  screenName: jsonData.screenName,
                  tokenSecret: jsonData.tokenSecret
              }, () =&gt; {
                  window.twttr.widgets.createTimeline(
                  {
                      sourceType: 'likes',
                      screenName: this.state.screenName
                  },
                  document.getElementsByClassName("tweets-likes-container")[0],
                  {
                      width: '100%',
                      height: '100%',
                      related: 'twitterdev,twitterapi'
                  });
              });
          }
      }); 
  }
  
  componentWillUnmount() {
      this.isMountedTwitter = false;
  }
  
  render() {
      return (
          &lt;div className="twitter-container"&gt;
              &lt;div className="twitter-grid-container"&gt;
                  &lt;div className="twitter-grid-item-1"&gt;
                      &lt;div className="twitter-left-categories-container"&gt;
                          &lt;div className="twitter-profil-container"&gt;
                              { this.state.name }
                          &lt;/div&gt;
                          &lt;TwitterCategoriesCard
                              pictureUrl={this.state.pictureUrl}
                              screenName={this.state.screenName}
                          /&gt;    
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div className="feed-container"&gt;
                      {/* &lt;div className="twitter-user-profil"&gt;
                          &lt;div className="twitter-header-profile"&gt;
  
                          &lt;/div&gt;
                          &lt;div className="tweets-profile-container"&gt;
  
                          &lt;/div&gt;
                      &lt;/div&gt; */}
                      &lt;div className="tweets-likes-container"&gt;
  
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div className="twitter-grid-item-3"&gt;
                      &lt;div className="twitter-rl-container"&gt;
                          &lt;div className="twitter-groups-container"&gt;
                              &lt;SearchTwitterPeople /&gt;
                              &lt;AvailableTrends /&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                      &lt;div className="twitter-rr-container"&gt;
                          &lt;div className="twitter-friends-container"&gt;&lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      );
  }
  }
  
  export default withAuth(Twitter);
  </code></pre>
  
  <p>TwitterCategoriesCard component</p>
  
  <pre><code>class TwitterCategoriesCard extends React.Component {
  constructor(props) {
      super(props);
  
      this.onExploreClick = this.onExploreClick.bind(this);
  }
  
  onExploreClick() {
      this.props.history.push("/twitter/explore");
  }
  
  render() {
      return (
          &lt;div className="twitter-categories-container"&gt;
              &lt;ul className="list-group twitter-categories-list"&gt;
                  &lt;li className="list-group-item list-group-item-hover"&gt;
  
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;i className="fas fa-home"&gt;&lt;/i&gt; Home
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li onClick={this.onExploreClick} className="list-group-item list-group-item-hover"&gt;
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;span style={{ fontWeight: '900' }}&gt;#&lt;/span&gt; Explore
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li className="list-group-item list-group-item-hover"&gt;
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;i className="fas fa-clock"&gt;&lt;/i&gt; Timeline likes
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li className="list-group-item list-group-item-hover"&gt;
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;i className="fas fa-bell"&gt;&lt;/i&gt; Notifications
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li className="list-group-item list-group-item-hover"&gt;
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;i className="far fa-envelope"&gt;&lt;/i&gt; Messages
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li 
                      className="list-group-item list-group-item-hover"
                  &gt;
                      &lt;div className="twitter-categories-icons-box"&gt;
                          &lt;img 
                          src={this.props.pictureUrl} 
                          alt="Avatar" 
                          className="twitter-categories-avatar"
                          /&gt; Profile
                      &lt;/div&gt;
                  &lt;/li&gt;
                  &lt;li className="list-group-item list-group-item-hover add-tweet-button"&gt;
                      &lt;a 
                          className="twitter-share-button"
                          href="https://twitter.com/intent/tweet"
                          data-size="large"
                      &gt;
                          Tweet
                      &lt;/a&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/div&gt;
      );
  }
  }
  
  export default withRouter(TwitterCategoriesCard);
  </code></pre>
  
  <p>withAuth HOC:</p>
  
  <pre><code>export default function withAuth(AuthComponent) {
  const Auth =  new AuthService();
  let customAuthComponent = false;
  
  class AuthWrapped extends React.Component {
      componentDidMount() {
          customAuthComponent = true;
  
          if(!Auth.loggedIn()) {
              this.props.history.replace("/login");
          } else {
              let twitterJwtToken = Auth.getTwitterToken();
              let facebookJwtToken = Auth.getToken();
              try {
                  if(twitterJwtToken) {
                      customAuthComponent &amp;&amp; this.props.history.replace("/twitter");
                  }
                  if(facebookJwtToken) {
                      customAuthComponent &amp;&amp; this.props.history.replace("/dashboard");
                  }
              } catch(err) {
                  if(twitterJwtToken) {
                      Auth.logoutTwitter();
                  }
                  if(facebookJwtToken) {
                      Auth.logout();
                  }
                  this.props.history.replace("/login");
              }
          }
      }
  
      componentWillUnmount() {
          customAuthComponent = false;
      }
  
      render() {
          if(Auth.loggedIn()) {
              return (
                  customAuthComponent &amp;&amp; &lt;AuthComponent history={this.props.history} /&gt;
              );
          } else {
              return null;
          }
      }
  }
  return AuthWrapped;
  }
  </code></pre>
  
  <p>App.js</p>
  
  <pre><code>function App() {
  return (
  &lt;Provider store={store} &gt;
    &lt;Router&gt;
      &lt;div className="App"&gt;
        &lt;I18nextProvider i18n={i18next}&gt;
          &lt;Header /&gt;
            &lt;Route exact path="/settings" component={Settings} /&gt;
            &lt;Route exact path="/twitter" component={Twitter} /&gt;
            &lt;Route exact path="/twitter/explore" component={TwitterExplore} /&gt;
        &lt;/I18nextProvider&gt;
      &lt;/div&gt;
    &lt;/Router&gt;
  &lt;/Provider&gt;
  );
  }
  
  export default App;
  </code></pre>