首页 > 解决方案 > 无法更新组件中的组件(`App`)错误

问题描述

我有以下组件:

import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import DashboardContext from '../../contexts/DashboardContext';
import authorizeWorker from '../../workers/authorize-worker';

/**
 * A protected route that calls the authorize API and redirects to login
 * on fail
 * @param {Function} component The component to redirect to on success 
 */
const ProtectedRoute  = ({ component }) => {
    const [isAuthenticated, setIsAuthenticated] = useState(null);
    const dashboardContext = useContext(DashboardContext);
    dashboardContext.setIsDashboard(true);
    const Component = component;

    useEffect(() => {
        authorizeWorker({})
            .then(() => setIsAuthenticated(true))
            .catch(() => setIsAuthenticated(false));
    }, []);

    if (isAuthenticated === true) {
        return <Component />;
    }

    if (isAuthenticated === false) {
        return <Redirect to="/login" />;
    }

    return null;
}

ProtectedRoute.propTypes = {
    component: PropTypes.func
};

export default ProtectedRoute;

我将它用于我的路由器,例如

<ProtectedRoute path="/projects" component={Projects} />

我最近在控制台中看到一个警告:Warning: Cannot update a component (App ) while rendering a different component (ProtectedRoute ). To locate the bad setState() call insideProtectedRoute , follow the stack trace as described。为什么我会看到此错误,我该如何解决?

标签: javascriptreactjs

解决方案


该错误是因为在初始渲染阶段,您渲染组件setIsDashboard(true);,通常,您希望在安装时执行它(useEffect使用空的 dep 数组)。

有一个初始渲染阶段,然后是挂载阶段,参见组件的生命周期图

确保它setIsDashboard是持久的,这意味着它是由 React API 创建的(如useState)。

或者用useMemo/来记忆它,或者你会得到 inifite 循环,因为在每次渲染时都会创建useCallback一个新的实例,并且 dep 数组 ( ) 将导致另一个执行。setIsDashboard[setIsDashboard]

const ProtectedRoute = ({ component }) => {
  const { setIsDashboard } = useContext(DashboardContext);

  // Make sure `setIsDashboard` persistant
  useEffect(() => {
    setIsDashboard(true);
  }, [setIsDashboard]);

  ...
};

推荐阅读