反应 useReducer 不更新状态

React useReducer not updating state

我正在使用 useReducer 在用户登录失败时更新 errorsState。我读过很多解决方案,据说 dispatch 是异步的,我知道这一点,所以我将 console.log 放在 useEffect 中以查看 errorsState 的变化,但不幸的是没有改变。这是我的代码

Login.jsx

export default function Login({ userProps }) {
  //
  // some variables and state
  //
  const { loading, user } = useLogin({ email: state.email }, state.submitted)
  const [errors, dispatch] = useReducer(errorsReducer, errorsState)

  useEffect(() => {
    console.log("errors", errors) // it won't triggered because errors state didn't updating from UseLogin
  }, [errors])

  return content
}

这里是获取函数useLogin

AuthAction.js

export const useLogin = (data, submitted) => {
  const [state, dispatch] = useReducer(userReducer, userState)
  const [errors, errorsDispatch] = useReducer(errorsReducer, errorsState)

  useEffect(() => {
    if (!submitted) return

    dispatch({
      type: USER_ACTIONS.MAKE_REQUEST,
    })

    ticketApi.login(data).then(({ res, status }) => {
      if (status !== "failed") {
        // Save to local storage
        const { token } = res
        // set token to local storage
        localStorage.setItem("jwtToken", token)
        // Set token to Auth Header
        setAuthToken(token)
        // decode token to get user data with jwt-decode
        const decoded = jwt_decode(token)
        // set current user
        return dispatch({
          type: USER_ACTIONS.GET_USER,
          payload: decoded,
        })
      }

      dispatch({
        type: USER_ACTIONS.END_REQUEST,
      })

      return errorsDispatch({
        type: ERRORS_ACTIONS.GET_ERRORS,
        payload: res.response.data,
      })
    })
  }, [submitted])

  return state
}

我试过将 console.log 放在 ERRORS_ACTIONS.GET_ERRORS 中以查看响应,没问题。 那我哪里错了?

useReducer 允许您更好地管理复杂状态,它不是状态容器,您在那里所做的是创建 2 种不同的状态,一个在 useLogin 中,另一个在您的 Login 组件,return errors 来自您的 useLogin 挂钩,以便登录组件可以看到它。

登录

export default function Login({ userProps }) {
  //
  // some variables and state
  //
  const { loading, user, errors } = useLogin({ email: state.email }, state.submitted)

  useEffect(() => {
    console.log("errors", errors)
  }, [errors])

  return content
}

使用登录

export const useLogin = (data, submitted) => {
  const [state, dispatch] = useReducer(userReducer, userState)
  const [errors, errorsDispatch] = useReducer(errorsReducer, errorsState)

  useEffect(() => {
    if (!submitted) return

    dispatch({
      type: USER_ACTIONS.MAKE_REQUEST,
    })

    ticketApi.login(data).then(({ res, status }) => {
      if (status !== "failed") {
        // Save to local storage
        const { token } = res
        // set token to local storage
        localStorage.setItem("jwtToken", token)
        // Set token to Auth Header
        setAuthToken(token)
        // decode token to get user data with jwt-decode
        const decoded = jwt_decode(token)
        // set current user
        return dispatch({
          type: USER_ACTIONS.GET_USER,
          payload: decoded,
        })
      }

      dispatch({
        type: USER_ACTIONS.END_REQUEST,
      })

      return errorsDispatch({
        type: ERRORS_ACTIONS.GET_ERRORS,
        payload: res.response.data,
      })
    })
  }, [submitted])

  return { ...state, errors };
}