Optimize Context

The way that context works is that whenever the provided value changes from one render to another, it triggers a re-render of all the consuming components (which will re-render whether or not they're memoized).
So take this for example:
type CountContextValue = readonly [number, Dispatch<SetStateAction<number>>]
const CountContext = createContext<CountContextValue | null>(null)

function CountProvider(props) {
	const [count, setCount] = useState(0)
	const value = [count, setCount]
	return <CountContext value={value} {...props} />
}
Every time the <CountProvider /> is re-rendered, the value is brand new, so even though the count value itself may stay the same, all component consumers will be re-rendered.
This can be problematic in certain scenarios.
The quick and easy solution to this problem is to memoize the value that you provide to the context provider:
type CountContextValue = readonly [number, Dispatch<SetStateAction<number>>]
const CountContext = createContext<CountContextValue | null>(null)

function CountProvider(props) {
	const [count, setCount] = useState(0)
	const value = useMemo(() => [count, setCount], [count])
	return <CountContext value={value} {...props} />
}
By memoizing the value, you're ensuring that the value is only re-created when the count value changes. As a result, the consuming components will only rerender when the count value changes.