Context demo
React.createContext must live outside a component. at module scope.
export const ThemeContext = React.createContext(...)
Code
Render
const AssContext = React.createContext("default value, in case no prodiver, check it.");
const page = () => {
// could declare const [x, setX] = useState()
// pass it into Provider value
return (
<>
{/* sec1, has provider value */}
<AssContext.Provider value="switcharoooo">
<Section1 />
</AssContext.Provider>
{/* sec2, no provider. hook */}
<Section1 />
{/* sec2, no provider. old school */}
<Section2 />
</>
);
};
const Section1 = () => {
const ass = useContext(AssContext);
return (
<div>
<h1>Section1</h1>
<p>{ass}</p>
</div>
);
};
const Section2 = () => {
return (
<div>
<h1>Section2</h1>
<AssContext.Consumer>
{(ass) => {
return <p>{ass}</p>;
}}
</AssContext.Consumer>
</div>
);
};
Section1
switcharoooo
Section1
default value, in case no prodiver, check it.
Section2
default value, in case no prodiver, check it.
Context provider can be inserted multiple times in multiple levels to change the value for consumer.
Add slick abstractions
type AssContextType = {
state: string;
setState: React.Dispatch<React.SetStateAction<string>>;
} | null;
const AssContext = React.createContext<AssContextType>(null);
const AssProviderlol = ({ children }: PropsWithChildren) => {
const [state, setState] = useState("now this is first state");
return <AssContext.Provider value={{ state, setState }}>{children}</AssContext.Provider>;
};
const useAss = () => {
const ass = useContext(AssContext);
if (!ass) throw "ass used outside of provider";
return ass;
};
Good.
ass.state is not null TS error.
ass.state might be nullconst ass = useAss();
return (
<div>
<h1>Section1</h1>
<p>{ass.state}</p>
</div>
);
<div>
<h1>Section2</h1>
<AssContext.Consumer>
{(ass) => {
return <p>{ass.state}</p>;
}}
</AssContext.Consumer>
</div>
Re-renders
When context state changes, all components that call useAss() re-render.
Implications.
Can't put big global state store in context.
{
theme, language, userName, currency, showSideNav
}
Because one item changes, all components that call useAss() re-render. Not only ones that need currency, or showSideNav
Solutions:
Split context. 1 for theme, 1 for user, 1 for language... etc
Install global store dependency. Allows to subscribe per field.