'how to call the useContext function?
im using the useContext from react , i have add boolean state to context but when i use it in the component it's give me typeErro : the setState is not a function
what im doing wrong this is my code ?
// context file
import { createContext, useContext, Dispatch, SetStateAction } from 'react';
interface TasksContextType {
isSubmitLoading: boolean;
setIsSubmitLoading: Dispatch<React.SetStateAction<boolean>>;
}
export const TasksContext = createContext({} as TasksContextType);
export const useTasksContext = () => {
const context = useContext<TasksContextType>(TasksContext);
if (!context) {
throw new Error('useTasksContext should be used within a TasksContext');
}
return context;
};
the provider file
//provider file
import React, { FC, useState } from 'react';
import { TasksContext } from './TasksContext';
export const TasksProvider: FC = ({ children }) => {
const [isSubmitLoading, setIsSubmitLoading] = useState<boolean>(false);
return (
<TasksContext.Provider
value={{
isSubmitLoading,
setIsSubmitLoading,
}}
>
{children}
</TasksContext.Provider>
);
};
the component where i use the useContext
//component
const { setIsSubmitLoading, isSubmitLoading } = useTasksContext();
useEffect(() => {
setIsSubmitLoading(mutation.isLoading);
}, [mutation, setIsSubmitLoading]);
Solution 1:[1]
You are checking if you are within your context provider by checking for a falsy value, but since you initialize context with a value ({}) it never will be undefined:
import { createContext, useContext, Dispatch, SetStateAction } from 'react';
interface TasksContextType {
isSubmitLoading: boolean;
setIsSubmitLoading: Dispatch<React.SetStateAction<boolean>>;
}
export const TasksContext = createContext({} as TasksContextType); // Here is your problem, change this to:
// createContext<TasksContextType | undefined>();
export const useTasksContext = () => {
const context = useContext<TasksContextType>(TasksContext); // You can remove the generic here, it will be inferred
if (!context) {
throw new Error('useTasksContext should be used within a TasksContext');
}
return context;
};
Now if you try to use the context somewhere you can't, it will throw an error useTasksContext should be used within a TasksContext
Or, if you use it within your context it should work ok.
Also note: You should be memoizing your value prop in TasksContext.Provider, otherwise it will be a new object every time and cause all consumers to rerender.
const value = useMemo(() => ({
isSubmitLoading,
setIsSubmitLoading,
}, [isSubmitLoading]) // you can skip setIsSubmitLoading as it is referentially stable
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Cal Irvine |
