Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clearTimeout() on componentWillUnmount #117

Closed
ricardojrgpimentel opened this issue Jan 10, 2018 · 15 comments
Closed

clearTimeout() on componentWillUnmount #117

ricardojrgpimentel opened this issue Jan 10, 2018 · 15 comments
Assignees

Comments

@ricardojrgpimentel
Copy link

I'm getting this error when i navigate to another page:

Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the ToastContainer component.

Shouldn't the component clearTimeout() when it unmounts?

@fkhadra
Copy link
Owner

fkhadra commented Jan 10, 2018

Hello @ricardojrgpimentel ,

Could you tell me which version you are using?

Thanks.

@fkhadra fkhadra self-assigned this Jan 10, 2018
@ricardojrgpimentel
Copy link
Author

@fkhadra I'm on 3.2.1

@fkhadra
Copy link
Owner

fkhadra commented Jan 10, 2018

Actually, the eventManager and react-transition-group use setTimeout.
Could you provide a snippet so I can reproduce the error?

I'll try to reproduce the issue on my side also.

@ricardojrgpimentel
Copy link
Author

ricardojrgpimentel commented Jan 10, 2018

I'm using react-router, and i have the ToastContainer inside ComponentA and ComponentB

When the route changes to something like /site/componentA the ComponentA gets mounted with ToastContainer along with a toast that lasts for 10 seconds, if i navigate to /site/componentB within those 10 seconds the same happens but this time i get the error stated above.

@fkhadra
Copy link
Owner

fkhadra commented Jan 10, 2018

Thanks for the explanation. I'll investigate.

@ricardojrgpimentel When you navigate the toast is active or not ?

@ricardojrgpimentel
Copy link
Author

It's active

@fkhadra
Copy link
Owner

fkhadra commented Jan 10, 2018

@ricardojrgpimentel I'm trying to reproduce the issue here:
Edit o4xkk1pq9y

Could you modify the snippet to fit your use case please ?

@gitneeraj
Copy link

@fkhadra
I have updated the code page to reproduce the error. Please check the Home Component and try to login. Also check console log for the error.

Please let me know the solution.

Thanks in advance.

@fkhadra
Copy link
Owner

fkhadra commented Feb 19, 2018

@RealNeeraj could you share the link? The sandbox is still showing the old code.

Thanks

@gitneeraj
Copy link

gitneeraj commented Feb 19, 2018

@fkhadra
https://codesandbox.io/s/64mml459z - Hopefully you can see it here now?

-------------------------------------------- Source code is here --------------------------------------------
import React from "react";
import { render } from "react-dom";
import {
BrowserRouter as Router,
Route,
Link,
Redirect
} from "react-router-dom";
import { ToastContainer, toast } from "react-toastify";

class Home extends React.Component {
constructor(props){
super(props);
this.state = {
redirect: false
}
}
componentDidMount() {
toast("HOME");
}
notify = () => {
toast.success("Logged in successfully !")
this.setState({
redirect: true
})
};

render() {
if(this.state.redirect){
return <Redirect to={'/about'} />
}
return (


Home



Login !

);
}
}

class About extends React.Component {
componentDidMount() {
toast("ABOUT");
}

render() {
return (


Home




);
}
}

const App = () => (


<button onClick={() => toast("hello")}>TOAST


  • Home


  • About

  <hr />

  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
</div>
);

render(, document.getElementById("root"));


Basically I would do a login and if its success I would want to show a success toast and redirect the user to inner page.

Hope it makes sense!

@fkhadra
Copy link
Owner

fkhadra commented Feb 19, 2018

The link is good now. Thanks

@fkhadra
Copy link
Owner

fkhadra commented Feb 19, 2018

@RealNeeraj toast.success("Logged in successfully !") will never works.

When the toast function is called, the ToastContainer will call setState, in the meantime you are calling setState({ redirect: true }) which unmount the ToastContainer.

This is why we get:

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the ToastContainer component.

Instead of putting ToastContainer inside each route component, put it on the App level like:

const App = () => (
  <Router>
    <div>
      <button onClick={() => toast("hello")}>TOAST</button>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
      </ul>
      <hr />
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <ToastContainer />
    </div>
  </Router>
);

@gitneeraj
Copy link

Thanks for being a great help @fkhadra

That solution makes more sense!

@fkhadra
Copy link
Owner

fkhadra commented Feb 19, 2018

You are welcome @RealNeeraj. @ricardojrgpimentel you were encountering that error probably for the same reason. I'll close the issue. Feel free to create a new one is the issue is not related.

@fkhadra fkhadra closed this as completed Feb 19, 2018
@ricardojrgpimentel
Copy link
Author

Sorry for the late answer, i moved the ToastContainer to the router component parent to fix it, like you said in the last comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants