Skip to content

Instantly share code, notes, and snippets.

@danalloway
Last active July 9, 2019 15:54
Show Gist options
  • Save danalloway/adb0efe07dc2270b3024fc25e6587fad to your computer and use it in GitHub Desktop.
Save danalloway/adb0efe07dc2270b3024fc25e6587fad to your computer and use it in GitHub Desktop.
React Providers using Context / State / Hooks
/**
* 1.) Context. For lifting our state up to any tree below the Provider.
*/
const ActivityContext = createContext()
/**
* 2.) Provider. For sharing our state across many render trees.
*/
export const ActivityProvider = ({ children }) => {
const [activity, setActivity] = useState([])
/**
* @function abort
* @returns {undefined}
*/
const abort = useCallback(() => abort(getRecentActivity), [])
/**
* @function loadActivity
* @async
* @returns {undefined}
*/
const load = useCallback(async () => {
try {
const result = await getRecentActivity()
if (!result || !result.ok || !result.body) {
throw new Error('Unable to fetch recent activity.')
}
setActivity(result.body.items)
} catch (err) {
log.error(err)
}
}, [])
return (
<ActivityContext.Provider value={{ abort, activity, load }}>
{children}
</ActivityContext.Provider>
)
}
/**
* 3.) Custom Hook. For consuming the shared state in any component within the Provider.
*/
export const useActivity = () => {
const context = useContext(ActivityContext)
if (context === undefined) {
throw new Error(`useActivity must be used within a ActivityProvider.`)
}
return context
}
/**
* 4a.) Use the Provider.
*
* <ActivityProvider>
* <YourComponent />
* <MaybeSomeOtherThing />
* </ActivityProvider>
*
* 4b.) Use the Hook.
*
* const YourComponent = (props) => {
* const { abort, activity, load } = useActivity()
*
* useEffect(() => {
* load()
* return abort
* }, [])
*
* return <ActivityItems items={activity} />
* }
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment