0

I have a problem with my code. Here is my code in App.tsx

   function App() {

  const dispatch = useDispatch();
  const auth = useSelector((state: RootStateOrAny) => state.auth);
  const token = useSelector((state: RootStateOrAny) => state.token);

  useEffect(() => {

    const firstlogin = localStorage.getItem('firstlogin');

    if(firstlogin) {
      const getUserToken = async () => {
        const res: any = await axios.post('/user/refresh_token', null);

        dispatch({type: "GET_TOKEN", payload: res.data.access_token});
      };
      getUserToken();
    }

  }, [auth.isLogged, dispatch]);

  useEffect(() => {
    if(token){
      const getUser = () => {
        dispatch(dispatchLogin());
        return fetchUser(token).then(res => {
          dispatch(dispatchGetUser(res))
        })
      }
      getUser();
    }
  },[token, dispatch]);

  return (
    <Router>
      <div className="App">
        <Header/>
        <Body/>
      </div>
    </Router>
  );
}

export default App;

And when I try to access the state in my Home component, which is under the Body component. It gives me an error saying: "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 a useEffect cleanup function."

This is my Home component:

import React from 'react';
import { useSelector, RootStateOrAny } from 'react-redux';

export default function Home() {
    
        const auth = useSelector((state: RootStateOrAny) => state.auth);
        const {username} = auth.user[0];

    return(
        <div>
            Welcome {username} !
        </div>
    )
};

And the Body Component:

export default function Body() {

    const auth = useSelector((state: RootStateOrAny) => state.auth);

    const {isLogged} = auth;
    
    return (
        <Switch>
            <Route path="/signup">
                {isLogged ? <Notfound/> : <Signup/>}
            </Route>
            <Route path="/login">
                {isLogged ? <Notfound/> : <Login/>}
            </Route>
            <Route path="/home">
                {isLogged ? <Home/> : <Login/>}
            </Route>
            <Redirect to="/home"/>
        </Switch>
    )
}

These are my reducers:

const initialState = {
    user: [],
    isAdmin: false,
    isLogged: false,
};

const authReducer = (state = initialState, action: any) => {
    switch(action.type) {
        case ACTIONS.LOGIN :
            return {
                ...state,
                isLogged: true
            }
        case ACTIONS.GET_USER : 
        return {
            ...state,
            user: action.payload.user
        }
        default:
            return state
    }
}

How can I fix this? Thank you.

  • 1
    Can we see the Body / Home components?? Generally this would be when a callback or async function is resulting in trying to set the state of a component that is no longer being rendered (unmounted). The error is pretty clear once you understand the problem. You have to clean up and prevent those callbacks from happening during the component un mounting life cycle. – AlienWithPizza Oct 12 '21 at 04:17
  • See [axios cancellation](https://github.com/axios/axios#cancellation) for how to use a canceltoken to clear any in-flight requests on the occasion of React component unmounting. See also [this answer](https://stackoverflow.com/a/68467084/8690857) using it. – Drew Reese Oct 12 '21 at 04:23
  • Hello, I have already edited the post showing the Body and Home components. Thank you. – Loreto Tabio Oct 12 '21 at 04:58
  • I don't see where you are updating any state in either the `Body` or `Home` components. Is the state being updated in either of `Signup` or `Login` components? Are either of these attempting to set some local state when authenticating? Can you update your question to include reproduction steps and walk us through them? – Drew Reese Oct 12 '21 at 15:21

1 Answers1

1

if you are using conditional rendering in your routes,It leads to this kind of error.Since the component mount is defined by the conditional statement.For that you can use history.push("/") with conditional statements in the useeffect hook of your Home component. or you can check this Can't perform a React state update on an unmounted component

Naveenkumar M
  • 616
  • 3
  • 17