I am trying to pass setState
using create context but I have problem with declaring its default value. How I can do it so TS will not give me an error that types of properties are incompatible? How can declare its default value that it will actually fit type Dispatch<SetStateAction<string>>
?
import { createContext, useState, useEffect } from "react";
import useLocalStorage from "../../hooks/useLocalStorage/";
interface DarkModeContextProviderProps {
children?: React.ReactNode;
}
export const DarkModeContext = createContext({
isDarkMode: false,
darkModeState: "off",
toggleIsDarkMode: () => {},
setDarkModeState: () => {}, // ????
});
export const DarkModeContextProvider = ({
children,
}: DarkModeContextProviderProps) => {
const [isDarkMode, setIsDarkMode] = useState(false);
const [darkModeState, setDarkModeState] = useState("");
const [localStorageDarkMode, setLocalStorageDarkMode] = useLocalStorage(
"darkModeState",
darkModeState
);
const toggleIsDarkMode = () => {
setIsDarkMode((prev) => !prev);
};
const value = {
isDarkMode,
toggleIsDarkMode,
darkModeState,
setDarkModeState,
};
useEffect(() => {
setDarkModeState(localStorageDarkMode);
}, []);
useEffect(() => {
setLocalStorageDarkMode(darkModeState);
}, [darkModeState]);
return (
<DarkModeContext.Provider value={value}>
{children}
</DarkModeContext.Provider>
);
};
CodePudding user response:
You can do this creating a type/interface for the context
import type { Dispatch, SetStateAction } from "react";
interface IDarkModeContext {
isDarkMode: boolean;
darkModeState: string;
toggleIsDarkMode: Dispatch<SetStateAction<string>>;
setDarkModeState: Dispatch<SetStateAction<string>>;
}
export const DarkModeContext = createContext<IDarkModeContext>({
isDarkMode: false,
darkModeState: "off",
toggleIsDarkMode: () => {},
setDarkModeState: () => {},
});
CodePudding user response:
You cannot have a default state setter since you have to create your context outside and state setters only live inside a component. What you can do and that's common is to define a DarkModeContextInterface
and use it like so:
interface DarkModeContextInterface {
isDarkMode: boolean;
darkModeState: string;
toggleIsDarkMode: Dispatch<SetStateAction<string>>;
setDarkModeState: Dispatch<SetStateAction<string>>;
}
export const DarkModeContext = createContext<DarkModeContextInterface | null>(null)
Here is how you would use it:
// the "!" is to tell Typescript that it won't be null, the default value
cont {isDarkMode} = useContext(DarkModeContext)!;