我正在使用 redux/toolkit 處理簡單的 reactjs 登錄表單。我想dashboard在成功登錄后重定向到頁面。它拋出以下錯誤。我是 reactjs 的新手,如果我錯過了什么,請告訴我。
錯誤:
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;
登錄.js
const Login = () => {
function handleSubmit(model) {
dispatch(submitLogin(model));
}
return (
<Formsy onValidSubmit={handleSubmit} ref={formRef}>
<input type="text" placeholder="username" />
....
</Formsy>
)
}
應用程式.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;
uj5u.com熱心網友回復:
問題
您試圖在useNavigateReact 組件之外使用鉤子,這是一種無效的使用。React 鉤子必須在頂層呼叫,它們不能有條件地呼叫,在函式、回圈等中......
鉤子規則
解決方案
將導航功能傳遞給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>
);
}
鏈/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>
);
}
uj5u.com熱心網友回復:
當你使用 react hooks 時,有一些規則你不能繞過它們
- 您必須在組件或
函式的根級別呼叫 useHook() - 您不能進行有條件的 useHook() 呼叫
我想,但也許我錯了,你的這部分代碼發生了錯誤
export const submitLogin =
({
email,
password
}) =>
async dispatch => {
const history = useNavigate(); // x Wrong you can't call inside another function
...
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459693.html
