Skip to content

Instantly share code, notes, and snippets.

@srcrip
Created February 16, 2021 04:45
Show Gist options
  • Save srcrip/b75bcc6f0577ef192f589f401a41cb40 to your computer and use it in GitHub Desktop.
Save srcrip/b75bcc6f0577ef192f589f401a41cb40 to your computer and use it in GitHub Desktop.
Simple example of using a regular React context, and one with a provider
import React, { createContext, useState, useContext } from 'react'
import update from 'immutability-helper'
import './App.css'
const CounterContext = createContext()
const CounterProvider = ({ children }) => {
const [state, setState] = useState({
resources: [
{ name: 'stone', amount: 0 },
{ name: 'copper', amount: 0 },
{ name: 'lumber', amount: 0 }
]
})
return (
<CounterContext.Provider value={{ state, setState }}>
{children}
</CounterContext.Provider>
)
}
const AddResource = ({ name, amount }) => {
const { state, setState } = useContext(CounterContext)
function add () {
const index = state.resources.findIndex(x => x.name === name)
setState(update(state, {
resources: {
[index]: { amount: {$apply: x => x + amount } }
}
}))
}
return <button onClick={add}> Add Resource</button>
}
const Resource = ({ name, amount }) => {
return <div>{name}: {amount}</div>
}
const Resources = () => {
const { state } = useContext(CounterContext)
return <div>
{state.resources.map(({ name, amount }, index) => {
return <div key={index}>
<Resource name={name} amount={amount} />
<AddResource name={name} amount={1}/>
</div>
})}
</div>
}
const App = () => (
<CounterProvider>
<Resources />
</CounterProvider>
)
export default App
import React, { createContext, useReducer, useContext } from 'react'
import update from 'immutability-helper'
import './App.css'
const StoreContext = createContext()
const initialState = {
resources: [
{ name: 'stone', amount: 0 },
{ name: 'copper', amount: 0 },
{ name: 'lumber', amount: 0 }
]
}
const StoreProvider = ({ children }) => {
const [state, dispatch] = useReducer((state, action) => {
switch(action.type) {
case 'edit resource':
const { name, amount } = action
const index = state.resources.findIndex(x => x.name === name)
const newState = update(state, {
resources: {
[index]: { amount: {$apply: x => x + amount } }
}
})
return newState
default:
throw new Error()
};
}, initialState)
return (
<StoreContext.Provider value={{ state, dispatch }}>
{children}
</StoreContext.Provider>
)
}
const AddResource = ({ name, amount }) => {
const { dispatch } = useContext(StoreContext)
function add () {
dispatch({ type: 'edit resource', name, amount })
}
return <button onClick={add}> Add Resource</button>
}
const Resource = ({ name, amount }) => {
return <div>{name}: {amount}</div>
}
const Resources = () => {
const { state } = useContext(StoreContext)
return <div>
{state.resources.map(({ name, amount }, index) => {
return <div key={index}>
<Resource name={name} amount={amount} />
<AddResource name={name} amount={1}/>
</div>
})}
</div>
}
const App = () => (
<StoreProvider>
<Resources />
</StoreProvider>
)
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment