使用react-router-dom(v6)成功登录后Reactjs重定向到仪表板页面

2024-04-10

我正在使用 redux/toolkit 制作简单的 Reactjs 登录表单。我想重定向到dashboard登录成功后的页面。它抛出以下错误。我是 ReactJS 的新手,如果我错过了什么,请告诉我。

Error:

Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

authSlice.js

import { useNavigate } from 'react-router-dom';


export const submitLogin =
  ({
    email,
    password
  }) =>
  async dispatch => {
    const history = useNavigate();

    return jwtService
      .signInWithEmailAndPassword(email, password)
      .then(user => {
        history('/dashboard');
        return dispatch(loginSuccess());
      })
      .catch(error => {
        return dispatch(loginError(error));
      });
  };


const authSlice = createSlice({
    name: 'auth',
    initialState,
    reducers: {
        loginSuccess: ....
        loginError: ....
        logoutSuccess: ....
    },
    extraReducers: {},
});

export const { loginSuccess, loginError, logoutSuccess } = authSlice.actions;

export default authSlice.reducer;

Login.js

const Login = () => {
   function handleSubmit(model) {
     dispatch(submitLogin(model));
   }

   return (
       <Formsy onValidSubmit={handleSubmit} ref={formRef}>
           <input type="text" placeholder="username" />
           ....
       </Formsy>
    )
}

App.js

<Routes>
  <Route path="/dashboard" element={<ProtectedRoutes />}>
  <Route path="" element={<Dashboard />} />
  </Route>
  <Route exact path="/" element={<Login />} />
  <Route path="*" element={<PageNotFound />} />
</Routes>
import React from 'react';
import { useSelector } from 'react-redux';
import { Navigate, Outlet } from 'react-router-dom';

const useAuth = () => {
    const auth = useSelector(({ auth }) => auth);
    return auth && auth.loggedIn;
};

const ProtectedRoutes = () => {
    const isAuth = useAuth();
    return isAuth ? <Outlet /> : <Navigate to="/" />
}

export default ProtectedRoutes;


Issue

您正在尝试使用useNavigatehook 在 React 组件之外,这是无效的使用。 React hooks 必须在顶层调用,不能有条件地、在函数、循环等中调用。

钩子规则 https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

解决方案

将导航功能传递给submitLogin动作创造者。

export const submitLogin = ({ email, password }, navigate) =>
  async dispatch => {
    return jwtService
      .signInWithEmailAndPassword(email, password)
      .then(user => {
        navigate('/dashboard');
        return dispatch(loginSuccess());
      })
      .catch(error => {
        return dispatch(loginError(error));
      });
  };

...

const Login = () => {
  const navigate = useNavigate();

  function handleSubmit(model) {
    dispatch(submitLogin(model, navigate));
  }

  return (
    <Formsy onValidSubmit={handleSubmit} ref={formRef}>
      <input type="text" placeholder="username" />
      ....
    </Formsy>
  );
}

Chain/await返回的 Promise

export const submitLogin = ({ email, password }) =>
  async dispatch => {
    return jwtService
      .signInWithEmailAndPassword(email, password)
      .then(user => {
        dispatch(loginSuccess());
        return user;
      })
      .catch(error => {
        dispatch(loginError(error));
        throw error;
      });
  };

...

const Login = () => {
  const navigate = useNavigate();

  async function handleSubmit(model) {
    try {
      await dispatch(submitLogin(model));
      navigate('/dashboard');
    } catch(error) {
      // handle error, log, etc...
    }
  }

  return (
    <Formsy onValidSubmit={handleSubmit} ref={formRef}>
      <input type="text" placeholder="username" />
      ....
    </Formsy>
  );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用react-router-dom(v6)成功登录后Reactjs重定向到仪表板页面 的相关文章

随机推荐