我正在 React 中处理登录/注册组件,我正在使用 useContext 和 useReducer 钩子来管理状态。这是我第一次尝试这种方式,我不确定为什么状态没有改变。以下是登录组件的文件。我已经展示了控制台记录的位置以及结果是什么。
这是API:
export const login = ({ email, password }) => {
console.log(email, password);
// jennifer@jennifer.com 12345678
return fetch(`${DEV_AUTH_URL}/signin`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
})
.then((res) => {
return res.ok
? res.json()
: res.json().then(err => PromiseRejectionEvent.reject(err));
})
.then(data => data);
};
这是状态管理器:
const AuthState = (props) => {
const initialState = {
token: null,
isAuth: false,
errorMsg: null,
user: {},
};
const [state, dispatch] = useReducer(AuthReducer, initialState);
const history = useHistory();
const handleLogin = (formData) => {
login(formData)
.then((res) => {
console.log(res);
// {token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7I…zk3fQ.Qx9zDeXBecToIEScCTDXzkBiTnATHab4cnyg0aSMdLE"}
res && res.token
? dispatch({ type: LOGIN_SUCCESS, payload: res })
: dispatch({ type: LOGIN_FAIL, payload: res });
})
.then(() => {
closeAllPopups();
console.log('jwt: ', localStorage.getItem('jwt'));
// {token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7I…zk3fQ.Qx9zDeXBecToIEScCTDXzkBiTnATHab4cnyg0aSMdLE"}
console.log('token: ', state.token);
// token: null
console.log('isAuth: ', state.isAuth);
// isAuth: false
history.push('/');
})
.catch((err) => dispatch({ type: LOGIN_FAIL, payload: err.toString() }));
};
这是减速器中的内容:
import {
LOGIN_SUCCESS,
LOGIN_FAIL,
} from '../types';
export default (state, action) => {
switch (action.type) {
case LOGIN_SUCCESS:
localStorage.setItem('jwt', action.payload.token);
return {
...state,
token: action.payload.token, // this is not changing state
isAuth: true, // this is also not changing state
};
case LOGIN_FAIL:
return {
...state,
token: null,
user: {},
isAuth: false,
errorMsg: action.payload,
};
default:
return state;
}
};
答案 0 :(得分:0)
有点不清楚您真正想要的逻辑流是什么,但 React 状态更新是异步的,并且 handleLogin
回调被调用的渲染周期中的状态在其生命周期内包含在回调范围内功能。仅仅因为 React 状态更新是异步的并不意味着它们都可以等待。
据我所知,您想调用 login
,登录成功后调度一个操作,关闭弹出窗口,记录一些值,然后导航回家。除了记录更新的状态外,这一切都可以在第一个 thenable
中完成。
const handleLogin = (formData) => {
login(formData)
.then((res) => {
console.log(res);
res?.token
? dispatch({ type: LOGIN_SUCCESS, payload: res })
: dispatch({ type: LOGIN_FAIL, payload: res });
closeAllPopups();
history.push('/');
})
.catch((err) => {
dispatch({ type: LOGIN_FAIL, payload: err.toString() });
});
};
使用 useEffect
钩子记录任何状态更新。
useEffect(() => {
console.log('jwt: ', localStorage.getItem('jwt'));
console.log('token: ', state.token);
console.log('isAuth: ', state.isAuth);
}, [state]);