reactjs - Hooks Context 给我循环渲染的错误,为什么?
问题描述
我开始学习 React Js。我试图用钩子创建一个身份验证。但我收到了错误:
Unhandled Rejection (Error): Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside
componentWillUpdate 或 componentDidUpdate。React 限制了嵌套更新的数量以防止无限循环。
这是我试图简化组件的代码,我希望它很清楚
export const AuthContext = React.createContext();
export const AuthProvider = ({children}) => {
const [currentUser, setCurrentUser] = useState(null);
useEffect( () => {
//const token = localStorage.getItem( 'token' );
//const userName = localStorage.getItem( 'userName' );
console.log('useEffect Auth Provider');
console.log(currentUser);
}, [] );
return (
<AuthContext.Provider
value={
[currentUser, setCurrentUser]
}
>
{children}
</AuthContext.Provider>
);
}
当我尝试登录 Login.js 时:
export const Login = () => {
const [ currentUser, setCurrentUser ] = useContext( AuthContext );
// Login
const handleLogin = (event) => {
event.preventDefault();
const { email, password } = event.target.elements;
console.log(email.value, password.value);
const siteUrl = clientConfig.serverUrl;
const loginData = {
email: email.value,
password: password.value
};
axios.post( `${siteUrl}/api/users/login`, loginData )
.then( res => {
setCurrentUser(res.data);
console.log(res.data);
});
}
if (currentUser) {
return <Redirect to="/" />
}
else {
return (
<form onSubmit={handleLogin}>
<input name="email" type="text" placeholder="E-Mail"></input>
<input name="password" type="password" placeholder="**************"></input>
<button type="submit">Login</button>
</form>
);
}
};
应用程序.js:
function App() {
return (
<AuthProvider>
<Router>
<Switch>
<PrivateRoute exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route path="*" component={NotFound} />
</Switch>
</Router>
</AuthProvider>
);
}
export default App;
// 私有路由
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import { AuthContext } from "../context/auth";
export const PrivateRoute = ({ component: RouteComponent, ...rest }) => {
const {currentUser} = useContext(AuthContext);
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} />
) : (
<Redirect to={"/login"} />
)
}
/>
);
};
我哪里错了?感谢任何想帮助我的人。马可·意大利
解决方案
这是您的代码的工作版本:
https://codesandbox.io/s/focused-dubinsky-yhpcl
问题在于您在 PrivateRoute 上访问当前用户的方式。它回来了undefined
。
const { currentUser } = useContext(AuthContext);
你不能像那样解构一个数组。所以我改成这样:
const [currentUser, setCurrentUser] = useContext(AuthContext);
注意:我知道您不需要setCurrentUser
on PrivateRoute
。但这只是使其按原样清晰工作的一种方法。你也可以这样做:
const [currentUser] = useContext(AuthContext);
// 这在您获得第一个数组值时有效
PrivateRoute.js
export const PrivateRoute = ({ component: RouteComponent, ...rest }) => {
console.log("Rendering PrivateRoute...");
const [currentUser, setCurrentUser] = useContext(AuthContext); // <-------------
console.log("currentUser: " + currentUser);
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} />
) : (
<Redirect to={"/login"} />
)
}
/>
);
};
推荐阅读
- python - 计算熊猫数据框列值和给定字符串之间的编辑距离
- javascript - 尝试引用 index.js 文件时,Visual Studio 无法识别 src 属性
- sql-server - 如何在 SQL 中检查数据库以确保其所有表都在使用中?
- python - 如何为 numpy ndarray 提供浮点索引?
- android - MediaPlayer: 错误 (1, -38) 在 Android 中有错误
- scala - Scala - 覆盖有边界的类型成员
- javascript - javascript中的默认“this”绑定
- clojure - 按包含所有值的基数-多字段过滤
- php - 使用 echo $children 时如何删除特定的子页面;在 WordPress 中
- logging - Logstash async appender 导致 java 应用程序由于 OOM 而停止