Not able to get state setter from context API, getting setGlobal is not a function

Viewed 68

I have an issue with a React app. I need to keep an array of items in my global state.

This is my hook :

import { useContext } from "react";
import GlobalContext from "../context/GlobalProvider";

const useGlobal = () => {
return useContext(GlobalContext);
}

export default useGlobal;

And this is my provider :

import { createContext, useState } from "react";
const GlobalContext = createContext({});

export const GlobalProvider = ({ children }) => {
const [global, setGlobal] = useState({});

return (
    <GlobalContext.Provider value={{ global, setGlobal }}>
        {children}
    </GlobalContext.Provider>
)
}

export default GlobalContext;

In my App.js I have:

import useGlobal from "../hooks/useGlobal.js";
const { setGlobal } = useGlobal();

const handleGotoA = () => {
    
    const id_G = item
    const id_G1 = item1
    const id_G2 = item2
    setGlobal({ id_G, id_G1, id_G2 });
   
}

I get a this error:

"setGlobal is not a function"

And I can't find nor understand the reason why, any help would be much appreciated.

4 Answers

Make sure you are calling this line const { setGlobal } = useGlobal() inside App function, not outside, as it's a hook, it should follow Rules of Hooks. Something like:

const App = ()={
 //...
 const { setGlobal } = useGlobal(); // inside and at the top level of the component
 //...
}

Also, global is a reserved name in JavaScript. To avoid confusions and possible errors, use another name, like globalData. And finally make sure App is wrapped inside GlobalProvider, like this:

<GlobalProvider >
  <App/>
</GlobalProvider>

useContext/useGlobal are hooks, so you cannot use them outside of a React component.

Also, make sure your hadleGoToA component is inside the GlobalContextProvider:

import useGlobal from "../hooks/useGlobal.js";

const HandleGotoA = () => { //Changed to uppercase to follow convention
    const { setGlobal } = useGlobal();

    const id_G = item
    const id_G1 = item1
    const id_G2 = item2
    setGlobal({ id_G, id_G1, id_G2 });
   
}

I think it has to do with this line

const { setGlobal } = useGlobal();

I think it should be:

const { setGlobal } = useGlobal;

Because with the parenthesis, you are calling the function, therefore setGlobal is the result of the useGlobal function instead of the function itself.

First You can't use hooks outside components or custom hooks. https://reactjs.org/docs/hooks-rules.html

//custom hook
const useHandleGoToA = () => {
  // this line moved inside the hook 
  const { setGlobal } = useGlobal();

  const id_G = item
  const id_G1 = item1
  const id_G2 = item2
  setGlobal({ id_G, id_G1, id_G2 });

}

// component
const ComponentA = () => {
  // this line moved inside the component. 
  const { setGlobal } = useGlobal();

  const id_G = item
  const id_G1 = item1
  const id_G2 = item2
  setGlobal({ id_G, id_G1, id_G2 });

  return null;
}
Related