What is `react-selector-context`?
npm install @borvik/react-selector-contextreact-selector-context?
useContext hook) re-renders any time anything on the context changed.
useContext hook nor static contextType. The context created here also returns a useSelector hook and a withSelector method tied to this context. It also returns a useSetter, useGetter and a useState.
value attribute you can pass to the provider.
value and the provider re-renders, it will reset the data store the the contents of value.
tsx
import { createContext } from '@borvik/react-selector-context';
const { Provider, Consumer, useSelector, withSelector } = createContext({
clicks: 0,
time: 0,
incrementClick: (_: number) => {},
});
`
createContext takes as it's only parameter the initial state of context - which behaves slightly differently than the built-in. With the built-in api, the initial state provided here is used when a Provider component isn't rendered. With this one, the Provider component is _required_, and the initial state is used if a value is not passed to the Provider.
With the exception of the value now being optional - the usage of the Provider is essentially the same.
`tsx
const SomeComponent: React.FC = ({ children }) => {
const [clicks, setClicks] = useState(0);
const [time, setTime] = useState(0);
useEffect(() => {
const interval = setInterval(() => setTime(v => v + 1), 1000);
return () => clearInterval(interval);
}, [setTime]);
const incrementClick = useCallback((by: number) => {
setClicks(v => v + by);
}, [setClicks]);
const value = useMemo(() => ({
clicks,
time,
incrementClick,
}), [clicks, time, incrementClick]);
return {children}
}
`
createContext also returns a paired useSelector hook. This hook is similar to the same hook found in react-redux and takes a single callback function to return the parts of the context you are interested in.
`tsx
const Clicker: React.FC = ({}) => {
const { clicks, incrementClick } = useSelector(cb => ({clicks: cb.clicks, incrementClick: cb.incrementClick}));
return (
Clicks: {clicks}
);
}
`
Here is an example using the Consumer.
`tsx
const Timer: React.FC = () => {
return
cb.time}>
{(time) => (Time: {time})}
;
}
`
And an example using withSelector as a higher-order-component.
`tsx
class TimerBase extends React.Component {
render() {
console.log('Render TIMER');
const { selectorValue: time } = this.props;
return Time: {time};
}
}
const Timer = withSelector(cb => cb.time)(TimerBase);
`
But, createContext here also returns some state-like functions useGetter, useSetter, and useState.
useGetter returns a fuction that will give you the full current state from the provider. This can be useful in event handlers where you don't really need your component to rerender as the state changes - but temporarily grabbing data to do validation is handy. Currently I don't have a proper example of this.
useSetter returns a function that allows you to alter the data inside the provider. You may specify a partial state, or a callback function that receives the current state and returns a partial state - just like React's built-in setState (for class components).
useState (not to be confused with React's version) takes selector callback function to get just the data you want, just like the useSelector - but, it returns a tuple, containing first the data you requested, but also the same setting function from useSetter.
`tsx
const { Provider, useState: useClickState } = createContext({
clicks: 0,
time: 0,
});
const Clicker: React.FC = () => {
const [clicks, setClickState] = useClickState(cb => cb.clicks);
return (
Clicks: {clicks}
);
}
``