Split state into multiple contexts using selectors
mainTo prevent unnecessary re-renders, you can pass selector functions to constate. Each selector splits the original hook's value into a separate React Context. This allows components to subscribe only to the specific part of the state they need.
Each selector function receives the value returned by useValue and returns the specific slice to be held by that context.
const [Provider, useCount, useIncrement] = constate(
useCounter,
(value) => value.count, // becomes useCount
(value) => value.increment, // becomes useIncrement
);import { useCallback, useState } from "react";
import constate from "constate";
function useCounter({ initialCount = 0 }) {
const [count, setCount] = useState(initialCount);
const increment = useCallback(() => setCount((prev) => prev + 1), []);
return { count, increment };
}
// Split the values into separate hooks
const [CounterProvider, useCount, useIncrement] = constate(
useCounter,
(value) => value.count,
(value) => value.increment,
);
function Button() {
// This component only re-renders if increment changes (which it won't)
const increment = useIncrement();
return <button onClick={increment}>+</button>;
}
function Count() {
// This component only re-renders when count changes
const count = useCount();
return <span>{count}</span>;
}
function App() {
return (
<CounterProvider initialCount={10}>
<Count />
<Button />
</CounterProvider>
);
}