Skip to content

Instantly share code, notes, and snippets.

@shannonmoeller
Last active October 18, 2022 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shannonmoeller/b41e741384ca2e251fbc9397bd743054 to your computer and use it in GitHub Desktop.
Save shannonmoeller/b41e741384ca2e251fbc9397bd743054 to your computer and use it in GitHub Desktop.
Look, Ma! No dispatcher!
import React, { createContext, useContext, useMemo, useState } from 'react';
export const NumberContext = createContext();
export function NumberContextProvider(props) {
const [state, setState] = useState({
number: 0,
});
// Using useState instead of useMemo so React doesn't garbage collect it.
// Using useState instead of useRef so we only create the actions once.
const [actions] = useState(() => ({
increment(amount = 1) {
setState((prev) => ({
...prev,
number: prev.number + amount,
});
},
decrement(amount = 1) {
setState((prev) => ({
...prev,
number: prev.number - amount,
});
},
}));
// Prevent React from triggering needless rerenders.
const value = useMemo(
() => [state, actions],
[state, actions]
);
return <NumberContext.Provider {...props} value={value} />;
}
export function useNumberContext() {
return useContext(NumberContext);
}
import React from 'react';
import { useNumberContext } from './context.js';
export function Counter() {
const [state, actions] = useNumberContext();
return (
<div>
<button onClick={() => actions.decrement()}>-1</button>
{` ${state.number} `}
<button onClick={() => actions.increment(2)}>+2</button>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment