我有以下组件:
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 (
应用程序) while rendering a different component (
protected 路由 ). To locate the bad setState() call inside
protected 路由 , follow the stack trace as described
。为什么我会看到此错误以及如何修复它?
最佳答案
该错误是因为在初始渲染阶段,您使用 setIsDashboard(true);
渲染组件,通常,您希望在挂载时执行此操作 ( useEffect
与空 dep 数组)。
There is an initial render phase, then mount phase, see component's lifecycle diagram.
确保 setIsDashboard
是持久的,这意味着它是由 React API 创建的(如 useState
)。
或者使用 useMemo
/useCallback
进行内存,否则您将得到无限循环,因为在每次渲染时都会创建一个 setIsDashboard
的新实例并且 dep 数组 ([setIsDashboard]
) 将导致另一次执行。
const ProtectedRoute = ({ component }) => {
const { setIsDashboard } = useContext(DashboardContext);
// Make sure `setIsDashboard` persistant
useEffect(() => {
setIsDashboard(true);
}, [setIsDashboard]);
...
};
关于javascript - 无法更新组件 (`App` ) 组件中出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62372917/