【问题标题】:Using redux's useDispatch in a custom hook yields an error在自定义钩子中使用 redux 的 useDispatch 会产生错误
【发布时间】:2019-10-24 14:02:42
【问题描述】:

我正在尝试在调度 redux 操作的自定义挂钩中实现 useDispatch,但出现以下错误:

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

代码:

模块文件

import { useDispatch, useSelector } from 'react-redux'

export function useFetchEvents() {
  const dispatch = useDispatch()
  const { items, loading } = useSelector(state => state.events)
  if (items.length === 0) {
    dispatch(requestEvents(true))
  }
}

功能组件

import { useFetchEvents } from '../../../modules/events'

const FrontPage = () => {
  return(
    <div>
      Front Page
      <button onClick={useFetchEvents}>
        Fetch events
      </button>
    </div>
  )
}

export default FrontPage

我已经看到错误并阅读了有关挂钩的规则,但如果我理解正确,我应该能够在自定义挂钩中使用 useDispatch。就像在以下工作示例中一样:

https://github.com/mikeour/drinks_drinks_drinks/blob/master/src/hooks/index.js

【问题讨论】:

  • 不能在return语句中使用useFetchEvents
  • 这会使从按钮调度动作变得非常复杂。有参考吗?
  • 为什么你的钩子没有返回声明?所有的钩子都会返回一些东西
  • @mthrsj 返回并不是我的例子的重点,钩子需要更新商店,这是重点。
  • @istvan 从返回中取出钩子确实解决了它。但是我该如何处理 onChange 或 onClick 的情况,我希望用户交互在哪里调度一个动作?

标签: reactjs redux react-redux


【解决方案1】:

那么每次调用中的钩子调用次数应该相同(这就是为什么不允许在if 语句中调用钩子的原因)。

要实现这个useFetchEvents钩子应该返回一个可以有条件调用的函数,例如点击

像这样改变useFetchEvents

export function useFetchEvents() {
  const dispatch = useDispatch()
  const { items, loading } = useSelector(state => state.events)
  return () => {
      if (items.length === 0) {
        // Redux action. requestEvents returns object with type.
        dispatch(requestEvents(true))
      }
  }
}

然后在你的组件中这样做:

const FrontPage = () => {
  const fetchEvents = useFetchEvents()

  return(
    <div>
      Front Page
      <button onClick={() => fetchEvents()}>
        Fetch events
      </button>
    </div>
  )
}

【讨论】:

  • @S.Schenk 添加了解释
猜你喜欢
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 2019-12-17
  • 1970-01-01
  • 2020-08-28
  • 2018-07-15
  • 2021-11-28
相关资源
最近更新 更多