0

I have a context:

export const AppConstArrays = createContext({
    neededHours: [],
    setNeededHours: (neededHours: INeededHours[]) => { },
    serviceTypes: [],
    setServiceserviceTypes: (serviceTypes:IServiceTypes[]) => { },
});

I am able to use the set functions in a data service this works with no error.

ArraysState.setNeededHours(neededHours);
ArraysState.setServiceserviceTypes(services);

When I try to use it elsewhere,

export default function reCalc(index:number) {  //This is not a function component?
    const ArraysState = React.useContext(AppConstArrays);

}

The tslinter is OK but at run time, I get the nasty 321 :-)

sp-webpart-workbench-assembly_en-us_8439e1230cb8ca442df6f89cf19f89a6.js:1 Uncaught Invariant Violation: Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321
Hooks can only be called inside of the body of a function component

truth be told, I do not have a provider anywhere for it because I use it in a .ts file Any help? Thank yeAll

Ofer Gal
  • 707
  • 1
  • 10
  • 32

1 Answers1

0

As it states in the link in the error message:

Hooks can only be called inside of the body of a function component

Here it means that you can't call React.useContext outside of a function component.

You should not use values in a React Context anywhere outside of React components. If you need to do so, you can simply pass them as input arguments from your components to those functions (say reCalc).

For example if you want to call setNeededHours in an API caller function, it can be like this:

function MyComponent() {
  const { setNeededHours } = React.useContext(AppConstArrays)

  React.useEffect(() => {
    fetchSomething({ /* input data */ }, setNeededHours)
  }, [])

  return <div>Some Content</div>
}

I hope it helps.

Hossein Moradi
  • 558
  • 1
  • 8
  • 16
  • Thank you but no. I have another context that works fine in same functions. I will try to move the value to the context that works and see. In any way thank you for answering – Ofer Gal Jun 23 '20 at 13:13
  • Anytime. Yes, it may work (depending on where/how it is called) but it's really fragile and can introduce unexpected issues likes this. It's better to follow the standard practices to avoid such problems. – Hossein Moradi Jun 24 '20 at 21:13