Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork93
diegohaz/constate
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Write local state usingReact Hooks and lift it up toReact Context only when needed with minimum effort.
| 🕹 CodeSandbox demos 🕹 | ||||
|---|---|---|---|---|
| Counter | I18n | Theming | TypeScript | Wizard Form |
importReact,{useState}from"react";importconstatefrom"constate";// 1️⃣ Create a custom hook as usualfunctionuseCounter(){const[count,setCount]=useState(0);constincrement=()=>setCount(prevCount=>prevCount+1);return{ count, increment};}// 2️⃣ Wrap your hook with the constate factoryconst[CounterProvider,useCounterContext]=constate(useCounter);functionButton(){// 3️⃣ Use context instead of custom hookconst{ increment}=useCounterContext();return<buttononClick={increment}>+</button>;}functionCount(){// 4️⃣ Use context in other componentsconst{ count}=useCounterContext();return<span>{count}</span>;}functionApp(){// 5️⃣ Wrap your components with Providerreturn(<CounterProvider><Count/><Button/></CounterProvider>);}
importReact,{useState,useCallback}from"react";importconstatefrom"constate";// 1️⃣ Create a custom hook that receives propsfunctionuseCounter({ initialCount=0}){const[count,setCount]=useState(initialCount);// 2️⃣ Wrap your updaters with useCallback or use dispatch from useReducerconstincrement=useCallback(()=>setCount(prev=>prev+1),[]);return{ count, increment};}// 3️⃣ Wrap your hook with the constate factory splitting the valuesconst[CounterProvider,useCount,useIncrement]=constate(useCounter,value=>value.count,// becomes useCountvalue=>value.increment// becomes useIncrement);functionButton(){// 4️⃣ Use the updater context that will never trigger a re-renderconstincrement=useIncrement();return<buttononClick={increment}>+</button>;}functionCount(){// 5️⃣ Use the state context in other componentsconstcount=useCount();return<span>{count}</span>;}functionApp(){// 6️⃣ Wrap your components with Provider passing props to your hookreturn(<CounterProviderinitialCount={10}><Count/><Button/></CounterProvider>);}
npm:
npm i constate
Yarn:
yarn add constate
Constate exports a single factory method. As parameters, it receivesuseValue and optionalselector functions. It returns a tuple of[Provider, ...hooks].
It's anycustom hook:
import{useState}from"react";importconstatefrom"constate";const[CountProvider,useCountContext]=constate(()=>{const[count]=useState(0);returncount;});
You can receive props in the custom hook function. They will be populated with<Provider />:
const[CountProvider,useCountContext]=constate(({ initialCount=0})=>{const[count]=useState(initialCount);returncount;});functionApp(){return(<CountProviderinitialCount={10}> ...</CountProvider>);}
The API of the containerized hook returns the same value(s) as the original, as long as it is a descendant of the Provider:
functionCount(){constcount=useCountContext();console.log(count);// 10}
Optionally, you can pass in one or more functions to split the custom hook value into multiple React Contexts. This is useful so you can avoid unnecessary re-renders on components that only depend on a part of the state.
Aselector function receives the value returned byuseValue and returns the value that will be held by that particular Context.
importReact,{useState,useCallback}from"react";importconstatefrom"constate";functionuseCounter(){const[count,setCount]=useState(0);// increment's reference identity will never changeconstincrement=useCallback(()=>setCount(prev=>prev+1),[]);return{ count, increment};}const[Provider,useCount,useIncrement]=constate(useCounter,value=>value.count,// becomes useCountvalue=>value.increment// becomes useIncrement);functionButton(){// since increment never changes, this will never trigger a re-renderconstincrement=useIncrement();return<buttononClick={increment}>+</button>;}functionCount(){constcount=useCount();return<span>{count}</span>;}
If you find a bug, pleasecreate an issue providing instructions to reproduce it. It's always very appreciable if you find the time to fix it. In this case, pleasesubmit a PR.
If you're a beginner, it'll be a pleasure to help you contribute. You can start by readingthe beginner's guide to contributing to a GitHub project.
When working on this codebase, please useyarn. Runyarn examples to run examples.
MIT ©Diego Haz
About
React Context + State
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Contributors13
Uh oh!
There was an error while loading.Please reload this page.
