Souvik Ray
Souvik Ray

Reputation: 3038

React-redux `useSelector` complains about Invalid Hook call

I am building a dynamic submenu for a dropdown using React and Redux. The plan is that when the user clicks on dropdown menu, an API call will be made and based on the response of the API, a submenu will be created. Here is my dropdown menu file

MainMenu.js

import React, {useEffect} from 'react'
import CreateSubMenu from './utils/CreateSubMenu.js'
import fetchSubMenuData from './actions/submenuAction.js'

function getSubMenu(menu, level){
  if(level == "level1") {
      const updatedMenu = CreateSubMenu(menu)
      return updatedMenu
  }

// entry level function
const DropdownMenu = () => {
     useEffect(() => {
        fetchSubMenuData();
       }, [])

    let menu = {"menu": "Locations", "submenu": []}
    const updatedNavigation = getSubMenu(menu, "level1")
}

Below is the file that contains a function that looks for API response and adds submenu to the menu. The API is call is made when the dropdown menu is clicked

CreateSubMenu.js

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

const CreateSubMenu = (menu) => {
    const subMenuData = useSelector(state=> state.addMenu)
}

But in CreateSubMenu.js, I get this error Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This error occurs when I use useSelector inside the function.

What am I doing wrong?

Upvotes: 1

Views: 1189

Answers (2)

Benjamin
Benjamin

Reputation: 3656

Hooks cannot be called conditionally. In your code, you conditionally call CreateSubMenu if level == "level1"

  if(level == "level1") {
      const updatedMenu = CreateSubMenu(menu)
      return updatedMenu
  }

This breaks the rule of hooks.

Instead, call the useSelector before the condition, and pass the value as an argument.

const subMenuData = useSelector(state=> state.addMenu)
  if(level == "level1") {
      const updatedMenu = CreateSubMenu(menu, subMenuData)
      return updatedMenu
  }

Upvotes: 4

Sowam
Sowam

Reputation: 1756

In CreateSubMenu.js you probably export it in the wrong way - try adding

export default CreateSubMenu;

in the end of CreateSubMenu.js file

Upvotes: -1

Related Questions