- Notifications
You must be signed in to change notification settings - Fork9
## Auto-archived due to inactivity. ## Scoping helpers for building reusable components with Redux
License
DataDog/redux-doghouse
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
redux-doghouse is a library that aims to makereusable components easier to build with Redux byscoping actions and reducers to a particular instance of a component.
It includes tools to help you buildScoped Actions andScoped Reducers with minimal modifications to your code. That way, if you build a Redux store for aParent with anarbitrary number ofChildren (meaning there can be none, one, or a million of them), actions affectingChild A won't affectChild B throughChild Z.
You can read more about why we builtredux-doghouse, and our real-world use-case, in thisblog post.
npm install redux-doghouseCounters (Live Demo)
An app that renders an arbitrary number of<Counter>s, with the ability to change the value of one of them at a time, all of them at once, or only the ones with even or odd numbers
npm run countersAdds a scope to the output of a set of action creators
TheactionCreators should be in the same format that you would pass tobindActionCreators. e.g:
(value)=>({type:SET_FOO, value})
or
{foo:(value)=>({type:SET_FOO, value})}
It will thenscope each of these action creators, so that the resulting action will include thescopeID.
{foo:(value)=>({type:SET_FOO, value,scopeID:"[the specified scopeID]"})}
actionCreators(Function or Object): An action creator, or an object whose values are action creators. The values can also be nested objects whose values are action creators (or more nested objects, and so on).scopeID(String or Number): An identifier to include in any actions created by theactionCreators
(Object or Function): An object mimicking the original object, but with each function adding{ scopeID } to theObject that they return. If you passed a function asactionCreators, the return value will also be a single function.
import{scopeActionCreators}from'redux-doghouse';import{actionCreators}from'./my-actions';// Before scoping:actionCreators.foo('bar');// Will return{type:'SET_FOO',value:'bar'};/// After scoping:scopeActionCreators(actionCreators,'a').foo('bar')// Will return{type:'SET_FOO',value:'bar',scopeID:'a'}
Works similarly toscopeActionCreators, but with the added benefit ofinstanceof checking. This allows you to write a check to see whether or not a set of action creators is aninstanceof ScopedActionFactory.
For example, the includedbindActionCreatorsDeep function will intelligently bind an object tree of both scoped and un-scoped action creators, depending on whether it's passed plain objects orScopedActionFactory instances.
actionCreators(Function or Object): An action creator, or an object whose values are action creators
(ScopedActionFactory) A class of object with the following:
RunsscopeActionCreators(id) on theactionCreators that were passed to thenew ScopeActionFactory, and returns the result.
import{ScopedActionFactory}from'redux-doghouse';import{actionCreators}from'./my-actions';constscopeableActions=newScopedActionFactory(actionCreators);constactionCreatorsScopedToA=scopeableActions.scope('a');constactionCreatorsScopedToB=scopeableActions.scope('b');actionCreatorsScopedToA.foo('bar')// Will return{type:SET_FOO,value:'bar',scopeID:'a'}
Takes an object ofactionFactories and binds them all to adispatch function. By default, it will use Redux's includedbindActionCreators to do this, but you can specify abindFn to use instead.
actionFactories(Object or ScopedActionFactory): A single ScopedActionFactory, or an object whose values are ScopedActionFactories.dispatch(Function): A function to which the resulting action creators fromactionFactoriesshould be dispatched; usually this is thedispatchmethod of a Redux store- [
bindFn](Function): If specified, this function will be used to bind resulting action creators to thedispatch. If unspecified, Redux's nativebindActionCreatorswill be used by default.
(Object or ScopedActionFactory): An object mimicking the original object, but with eachScopedActionFactory generating functions that will immediately dispatch the action returned by the corresponding action creator. If you passed a single factory asactionFactories, the return value will also be a single factory.
import{createStore}from'redux';import{ScopedActionFactory,bindScopedActionFactories}from'redux-doghouse';import{actionCreators,reducers}from'./my-redux-component';conststore=createStore(reducers);constscopeableActions={myComponentActions:newScopedActionFactory(actionCreators);}constboundScopeableActions=bindScopedActionFactories(scopeableActions,store.dispatch);
Extends Redux's nativebindActionCreators to allow you to bind a whole tree of nested action creatorfunctions andScopedActionFactory instances to adispatch function.
actionCreatorTree(Object): An object whose values can be:- AFunction to be bound to the
dispatch - A
ScopedActionFactoryto be bound to thedispatch - AnotherObject containing either of these (or more nestedObject)
- AFunction to be bound to the
dispatch(Function): A function to which the members ofactionCreatorTreeshould be dispatched; usually this is thedispatchmethod of a Redux store
import{bindActionCreatorsDeep,ScopedActionFactory}from'redux-doghouse';import{createStore}from'redux';import{reducers}from'./my-reducers';conststore=createStore(reducers);constactionCreators={fooActions:{bar:(value)=>({type:'BAR', value})},barActions:{baz:newScopedActionFactory({quux:(value)=>({type:'QUUX'})})}}constboundActionCreators=bindActionCreatorsDeep(boundActionCreators,store.dispatch);
This acts as an extension of Redux'scombineReducers, which takes an object ofreducers in the form of{ [prop]: reducer(state, action) } pairs and combines them into a single reducer that returns{ [prop]: state } pairs.scopeReducers goes a step further and returns an object of{ [scopeID]: { [prop]: state} } pairs.
In other words, it will create a reference to yourreducers for each newscopeID you add to your data model, and route scoped actions to their correspondingscopeID when reducing a new state.
reducers(Object): An object whose keys correspond to property names, and whose values correspond to different reducing functions that need to be combined into one and reused across multiple scopes.
(Function): A reducer that takes an object of state objects in the form of{ [scopeID]: state } pairs, and an action that includes ascopeID. The reducer will return a new object mimicking the original object, but for each key:
- For the matching
scopeID, invoke thereducersto construct a new state object with the same shape as thereducers - Leave all the other
scopeIDs' state objects unchanged
// Given these actionCreators...import{scopeActionCreators}from'redux-doghouse';constreducers={foo:(state=0,action)=>{switch(action.type){case'INCREMENT_FOO':returnstate+1;case'DECREMENT_FOO':returnstate-1;default:returnstate;}}};constactionCreatorsA=scopeActionCreators({incrementFoo:()=>({type:'INCREMENT_FOO'})},'a');// Without scopingimport{combineReducers}from'redux';constcombinedReducers=combineReducers(reducers);conststate={foo:0};combinedReducers(state,actionCreatorsA.incrementFoo());// Will return{foo:1}// With scopingimport{scopeReducers}from'redux-doghouse';constscopedReducers=scopeReducers(reducers);conststate={a:{foo:0},b:{foo:2}};scopedReducers(state,actionCreatorsA.incrementFoo());// Will return{a:{foo:1},b:{foo:2}}
About
## Auto-archived due to inactivity. ## Scoping helpers for building reusable components with Redux
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
