首页 > 解决方案 > 在自定义钩子中使用 redux 的 useDispatch 会产生错误

问题描述

我正在尝试在调度 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

标签: reactjsreduxreact-redux

解决方案


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

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

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>
  )
}

推荐阅读