Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

State solution for React

License

NotificationsYou must be signed in to change notification settings

dev-afzalansari/react-tivity

Repository files navigation

State solution for React

Installation

npm

npm i react-tivity

yarn

yarn add react-tivity

Table of Contents

Introduction

Easy andSmall state management library forReact with hooks based api and zero configuration. Withreact-tivity you don't need to pass the selector in the hook you get the whole state that you can destructure and your components will get updated only when the value they are consuming is changed.

  • Zero boilerplate.
  • Zero configuration
  • Small & Easy.
  • Hooks based Api.
  • Typescript Support.

create

create takes anobject orinitializer and returns a hook to be used in components.

Example on StackBlitz

import{create}from'react-tivity'

Then initialize store by passingobject orinitializer

constuseCount=create({count:0,inc:state=>state.count++,dec:state=>state.count--})

Usage in react component

functionCounter(){let{ count, inc, dec}=useCount()return(<div><h1>{count}</h1><buttononClick={inc}>Count++</button><buttononClick={dec}>Count--</button></div>)}

Someapis are assigned to the hook and can be used in or outside of react component.

// you can get access to state objectletcount=useCount.state// calling methodscount.inc()count.dec()// reading valuescount.count// or setting valuescount.count++// subscribeletcallback=()=>console.log('count changed')letunsubscribe=useCount.subscribe(callback)// will log 'count changed' every time state value changes// to unsubscribe call the variable you assigned subscription tounsubscribe()

reduce

reduce takes areducer function as first argument andobject orinitializer which returns anobject as second argument. You can pass your stateobject without any method and retrieve dispatch function assigned tohook itself as method.

Example on StackBlitz

import{reduce}from'react-tivity'

Then initialize store by passingreducer &object orinitializer as second.

functionreducer(state,action){switch(action.type){case'inc':return{count:state.count+1}case'dec':return{count:state.count-1}}throwError('unknown action type')}constuseCount=reduce(reducer,{count:0})

Usage in react component.

functionCounter(){let{ count,dispatch:countDispatch}=useCount()return(<div><h1>{count}</h1><buttononClick={()=>countDispatch({type:'inc'})}>Count++</button><buttononClick={()=>countDispatch({type:'dec'})}>Count--</button></div>)}

Someapis are assigned to the hook and can be used in or outside of react component.

// all apis from create such as subscribe and state object are assigned// dispatchletdispatch=useCount.state.dispatchdispatch({type:'inc'})dispatch({type:'dec'})

persist

persist works same ascreate if only one argument is passed if passed two arguments firstreducer and secondobject it acts as reduce. It takes an additional propertyconfig which won't be saved as a state value. It will persist your stateobject in either storage created by itself or the custom storage you provide. It accepts asynchronous storage only, but for convenience you can pass 'local' or 'session' to create asynhronous localStorage & asyncronous sessionStorage respectively.

Example on Stackblitz

import{persist}from'react-tivity'

Then initialize store by passingobject orinitializer

// acts as createconstuseCount=persist({count:0,inc:state=>state.count++,dec:state=>state.count--,config:{key:'@count'// required,storage:'session'// defaults to 'local'}})// acts as reduceconstuseCount=persist(reducer,{count:0,config:{key:'@count',storage:'session'// defaults to 'local'}})

config property

constuseStore=persist({// First argument reducer you want it to act as `reduce` and then `object` or `initializer`// ...config:{// Only required property of configkey:'string',// Any asynchronous storage which has setItem, getItem and removeItem properties, defaults to 'local' can also accept 'session'storage:'local'|'session'|AsyncStorage,// To serialize the data to be saved in chosen storage, defaults to JSON.stringify()serialize:(state)=>JSON.stringify(state),// To deserialize saved data when retrieved from chosen storage, defaults to JSON.parse()deserialize:(state)=>JSON.parse(state),// An array of state slices not to save for eg. ['count'], defaults to []blacklist:[],// Required if you change your structure of your state otherwise optional, defaults to 0version:0,// Required if you have changed version, So you can migrate your previously saved state values to current one. defaults as below.migrate:(current,previous)=>current}})// More on migrate, In order to migrate between version change// You receive Current State & Previous State so you can decide what to keep what to throw, eg. belowconstmigrate=(curr,prev)=>{if(prev.version===0){current.upvotes=prev.likes// Current state's `upvotes` slice will get hydrated with value previous state's `likes`returncurrent// Return current now}}

Internal_status slice

Asynchronous storages will hydrate stores asynchronously it means that user can have a flash of initial state before storegets hydrated and the view gets updated. To overcome this problem a_status slice is managed internally. The value of_statusisfalse initially and when asynchronous task gets done it is set totrue so you can wrap your child components consumingthat state in a parent wrapper component to prevent flash of that initial state by rendering a loader component until store getshydrated.

// Note: `_status` property gets set to true even if there was no state saved in the storage.functionPersistWrapper(){let{ _status}=useCount()if(!_status)return<h1>Loading...</h1>return<ChildComponent/>}functionChildComponent(){// child component consuming useCount's state}

Someapis are assigned to the hook and can be used in or outside of react component.

// all apis from `create` and `reduce`// persistletpersist=useCount.persist// or just useCount.persist.clearStorage()persist.clearStorage()// clears the storage assigned to useCount

Typescript

create

typeState={count:number;inc:(state:State)=>void;dec:(state:State)=>void;}constuseCount=create<State>({count:number,inc:(state)=>state.count++,dec:(state)=>state.count--})

reduce

typeState={count:number;}typeAction={type:string;}functionreducer(state:State,action:Action){//....}constuseCount=reduce<State,Action>(reducer,{count:0,})

persist

If using ascreate same ascreate just add config.

typeState={count:number;inc:(state:State)=>void;dec:(state:State)=>void;config:{key:string;storage:string;}}constuseCount=create<State>({count:number,inc:(state)=>state.count++,dec:(state)=>state.count--,config:{key:'@count',storage:'session',}})

If using asreduce.

typeState={count:number;config:{key:string;storage:string;}}typeAction={type:string;}functionreducer(state:Omit<State,'config'>,action:Action){//....}// Pass second generic argument as true if you are using persist as reduceconstuseCount=reduce<State,true,Action>(reducer,{count:0,config:{key:'@count',storage:'session'}})

License

Licensed underMIT License

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp