【问题标题】:React useReducer not updating state反应 useReducer 不更新状态
【发布时间】:2021-01-17 17:38:32
【问题描述】:

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

登录.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。在一个上调度操作,检查另一个。
  • 我认为这是正确的。因为除了 errorsReducer 之外没有其他 errors 变量
  • 我知道这听起来很傻,但是......你的自定义钩子是大写的,它应该以小写use开头,尝试改变它
  • 没有任何变化,仍然无法正常工作
  • errorsState 来自哪里?

标签: javascript reactjs react-hooks use-reducer


【解决方案1】:

useReducer 可以让你更好地管理复杂的状态,它不是一个状态容器,你要做的是创建 2 个不同的状态,一个在 useLogin 内部,另一个在你的 Login 组件中,返回 @ 987654324@ 来自您的 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 };
}

【讨论】:

  • 是的,这是有道理的。我认为useReducer 的工作方式与redux 相同。非常感谢,但我已经开始使用 redux
猜你喜欢
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-08-13
  • 2021-08-17
相关资源
最近更新 更多