Skip to content

Instantly share code, notes, and snippets.

@brentsowers1
Last active January 22, 2021 21:54
Show Gist options
  • Save brentsowers1/e4793670a845ec22af265339f27e7ed5 to your computer and use it in GitHub Desktop.
Save brentsowers1/e4793670a845ec22af265339f27e7ed5 to your computer and use it in GitHub Desktop.
import React, { useState, useContext, createContext } from 'react';
// We have to define a context object for each unique piece of shared state.
// Parameter is the default value - in our case we're making it an object
// with a value, and a function to set that value. The Provider will
// populate the function
const CounterContext = createContext({
value: 0,
setValue: () => {},
});
// This will be a high level component in our application that can read from
// context. We'll sneak in a function to update the value inside of the
// context object so we can easily update it in children.
const CounterProvider = ({ children }) => {
const counterInitialState = {
value: 0,
setValue: newValue => {
// The actual context is an object with the value and function to update
// it (what we're defining now), but we only want to update the value
// itself. So we have to follow the reducer format (ugh) to return a new
// object with a new value for counterValue, but preserve the other keys
// in the object (this function)
// eslint-disable-next-line no-use-before-define
setCounterState(prevState => {
return {
...prevState,
value: newValue,
};
});
},
};
const [counterState, setCounterState] = useState(counterInitialState);
return (
<CounterContext.Provider value={counterState}>
{children}
</CounterContext.Provider>
);
};
const ContextExample = () => {
return (
<div>
<CounterProvider>
Main app container
<CounterDisplay />
<CounterIncrementer />
</CounterProvider>
</div>
);
};
const CounterIncrementer = () => {
// useContext will return the current version of what gets set as the value
// in the Provider. It's an object with two properties. You'll get a new
// value in here whenever it changes, it's very much like useState! In fact
// you could write this line as:
// const { value, setValue } = useContext(CounterContext)
const counter = useContext(CounterContext);
return (
<div>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label,react/button-has-type */}
Increment - <button onClick={() => counter.setValue(counter.value + 1)} />
</div>
);
};
const CounterDisplay = () => {
const counter = useContext(CounterContext);
return <div>Counter value = {counter.value}</div>;
};
export default ContextExample;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment