【问题标题】:How to fix, can't perform a React state update on an unmounted component?如何修复,无法对未安装的组件执行 React 状态更新?
【发布时间】:2021-11-30 17:17:33
【问题描述】:

我的代码有问题。这是我在 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;

当我尝试访问位于 Body 组件下的 Home 组件中的状态时。它给了我一个错误说:“警告:无法对未安装的组件执行 React 状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏。要修复,取消所有订阅和异步任务一个 useEffect 清理函数。”

这是我的 Home 组件:

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

还有正文组件:

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

这些是我的减速器:

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

我该如何解决这个问题?谢谢。

【问题讨论】:

  • 我们能看到 Body / Home 组件吗?通常,这将是当回调或异步函数导致尝试设置不再呈现(卸载)的组件的状态时。一旦你理解了问题,这个错误就很清楚了。您必须在组件卸载生命周期期间清理并防止这些回调发生。
  • 请参阅axios cancellation,了解如何在 React 组件卸载时使用取消令牌来清除任何正在进行的请求。另请参阅 this answer 使用它。
  • 您好,我已经编辑了显示 Body 和 Home 组件的帖子。谢谢。
  • 我看不到您在哪里更新 BodyHome 组件中的任何状态。 SignupLogin 组件中的状态是否正在更新?这些中的任何一个是否试图在身份验证时设置一些本地状态?您能否更新您的问题以包括复制步骤并引导我们完成这些步骤?

标签: javascript reactjs


【解决方案1】:

如果您在路由中使用条件渲染,则会导致这种错误。由于组件挂载是由条件语句定义的。为此,您可以将 history.push("/") 与条件语句一起使用Home 组件的 useeffect 钩子。 或者你可以检查这个Can't perform a React state update on an unmounted component

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 2021-07-01
    • 2020-11-21
    • 2021-06-19
    • 2019-11-09
    • 2019-05-30
    • 2021-05-30
    相关资源
    最近更新 更多