如何修复React自定义钩子中的``钩子只能在功能组件内部调用''错误?

时间:2019-11-06 17:15:10

标签: javascript reactjs react-hooks

[已解决]

我正在尝试创建一个自定义钩子,以在项目中使用。它应该提交有效负载并返回结果,但是出现此错误:

未捕获的不变违规:只能在函数组件的主体内部调用挂钩。

页面加载时在控制台中发生错误。我什至不需要单击该按钮。

这是我的自定义钩子(useSubmit):

import { useState } from 'react'

export const useSubmit = submitFunction => {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)

  const handleSubmit = async args => {
    try {
      setLoading(true)
      setError(null)
      return submitFunction(...args)
    } catch (error) {
      setError(error)
    } finally {
      setLoading(false)
    }
  }
  return [handleSubmit, loading, error]
}

这是我功能组件中的相关代码:

import React from 'react'
import { useSubmit } from '../../../../../../../utils/custom-hooks/use-submit'
import { createGameRules } from '../../../../../../services/game/rules'

export const GameRules = () => {
  const [handleSubmit, loading, error] = useSubmit(createGameRules)

  // Some code here

  const saveGameRules = async () => {
    const payload = {
      title: 'Some title',
      rules: 'Some description'
    }

    const savedGameRule = await handleSubmit(payload)
    console.log(savedGameRule)
  }

  // More code here

   return (
      <button onClick={() => saveGameRules()}>Save</button>
   )

这是我的服务,将数据发布到端点并返回结果:

import axios from '../../axios'

export const createGameRules = async payload => {
  const { title, rules } = payload
  const { data: { data } } = await axios({
    method: 'POST',
    url: '/game/rules',
    data: {
      title,
      rules
    }
  })

  return data
}

我想念什么? 谢谢您的帮助!


[编辑]

问题在于项目中还有另一个package.json文件。由于自定义钩子位于另一个package.json的层次结构中,因此该应用程序试图使用React的另一个版本。

解决方案是将自定义钩子移到更内部的位置,紧靠相应的package.json,因此一切正常。

线索出在某些人引用的链接https://reactjs.org/warnings/invalid-hook-call-warning.html上,但我不知道这个其他package.json

谢谢大家的帮助。

2 个答案:

答案 0 :(得分:1)

发生此错误的3个原因:

  1. 错误地使用了钩子-看来这不是您的情况
  2. 已加载重复的React
  3. Dom /反应库不匹配

我想这对您来说是2或3-检查您使用的是reactreact-dom的最新版本。

https://reactjs.org/warnings/invalid-hook-call-warning.html

答案 1 :(得分:0)

我不太确定。但这可能是您尚未导入反应的问题:

import { useState } from 'react'

import React, { useState } from 'react'

我猜是因为钩子只能在react函数内部使用。并且不导入react意味着您在react之外使用useState。


另一个culprit我发现您的代码存在问题:

  

请勿在事件处理程序中调用钩子。

要解决此问题,请将钩子逻辑移到handleSubmit函数之外。 handleSubmit是事件处理程序,您不能在event handler内调用钩子