在自定义钩子中使用redux的useDispatch会产生错误

时间:2019-10-24 14:02:42

标签: reactjs redux react-redux

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

1 个答案:

答案 0 :(得分:0)

然后,每次调用中的钩子调用次数应相同(这就是为什么不允许您在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>
  )
}