简体   繁体   中英

How to fix 'Hooks can only be called inside the body of a function component' error in React custom hook?

[SOLVED]

I am trying to create a custom hook to use in the project. It should submit a payload and return a result, but I am getting this error:

Uncaught Invariant Violation: Hooks can only be called inside the body of a function component.

The error happens in the console when the page loads. I don't even need to click on the button.

This is my custom hook (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]
}

This is the relevant code from my functional component:

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

Here is my service, to post the data to the endpoint and return the result:

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
}

What am I missing? Thanks for the help!!


[EDIT]

The problem was that there was another package.json file in the project. Because the custom hook was in the hierarchy of this other package.json, the application was trying to use another version of React.

The solution was to move the custom hook to a more internal level, next to the appropriate package.json, so everything worked.

The clue was at the link https://reactjs.org/warnings/invalid-hook-call-warning.html cited by some, but I didn't know about this other package.json

Thank you all for your help.

There are 3 reasons that this error occurs:

  1. using hooks wrongly - this doesn't seem to be your case
  2. Duplicate React loaded
  3. Mismatched Dom/React libraries

I would guess it would be 2 or 3 for you - check you are using the latest versions of react and react-dom .

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

I'm not pretty sure. But it might be the issue that you have not imported react:

import { useState } from 'react'

Do,

import React, { useState } from 'react'

I guess it because hooks can only be used inside react functions. And without importing react means you're using useState outside the react.


Another culprit I found the issue with your code is:

Do not call hooks in event handlers.

To solve this, move your hooks logic outside the handleSubmit function. handleSubmit is an event handler and you cannot call hooks inside event handler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM