首页 > 解决方案 > 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"} />
        )
      }
    />
  );
};

我哪里错了?感谢任何想帮助我的人。马可·意大利

标签: reactjsreact-hooks

解决方案


这是您的代码的工作版本:

https://codesandbox.io/s/focused-dubinsky-yhpcl

问题在于您在 PrivateRoute 上访问当前用户的方式。它回来了undefined

const { currentUser } = useContext(AuthContext);

你不能像那样解构一个数组。所以我改成这样:

const [currentUser, setCurrentUser] = useContext(AuthContext);

注意:我知道您不需要setCurrentUseron 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"} />
        )
      }
    />
  );
};

推荐阅读