在检查状态之前等待 thunk 完成 HTTP 请求

Wait for thunk to finish the HTTP request before checking state

我有点新,正在学习使用 thunk 的 React-Redux 阶段,所以我有这个 login 状态,它有 isLoggedIn 布尔值,我想检查它是否要用户重定向到主屏幕。

所以,我正在向我的 Node.JS 服务器发出 thunk 请求,returns 用户和我将 isLoggedIn 标志设置为 true,但是当我根据它验证它,我需要单击 Login 按钮两次以重定向。

我 99% 确定这是因为异步 thunk 行为,我的问题是如何解决它?

const Login = ({ authenticate, IsUserLoggedIn }) => {
        const [email, setEmail] = useState('');
        const [password, setPassword] = useState('')
        const history = useHistory()
    
        const onSubmit = e => {
            e.preventDefault();
            const user = {
                email,
                password
            }
            authenticate(user); //<---- Thunk Request
            if (IsUserLoggedIn) {      //<---- Initially false, set to true on successful login
                history.push('/tracker')
            }
        }
        return (
            <>
                <h3>Login</h3>
                <form onSubmit={onSubmit}>
                    <div className="form-control">
                        <label htmlFor="email">Email</label>
                        <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter email..." />
                    </div>
                    <div className="form-control">
                        <label htmlFor="Password">Password </label>
                        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Enter password..." />
                    </div>
                    <button className="btn">Login</button>
                </form>
            </>
        )
    }
    
    const mapStateToProps = state => ({
        IsUserLoggedIn: getIsUserLoggedIn(state)
    })
    
    const mapDispatchToProps = dispatch => ({
        authenticate: user => dispatch(getUser(user))
    })
    
    export default connect(mapStateToProps, mapDispatchToProps)(Login)

这是我的Thunk请求

export const getUser = user => async dispatch => {
    try {
        const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        }
        let body = JSON.stringify(user)
        const response = await axios.post('/api/v1/users/login',body, config)
        dispatch(setUserInfo(response))
    }
    catch (error) {
       dispatch(userError(error.response.data.error))
    }
}

这似乎是一个非常普遍的问题,但似乎找不到解决方案。让我知道是否需要更多代码

您可以尝试以下方法:

const Login = ({ authenticate, IsUserLoggedIn }) => {
  const history = useHistory();
  React.useEffect(() => {
    if (IsUserLoggedIn) {
      history.push('/tracker');
    }
  }, [IsUserLoggedIn, history]);

不确定 useHistory returns 是否每次都是同一个对象,但我认为是。