Federal
Minimalistic centralized React store
Why?
Federal wraps your react components, creating a centralized data store. It's similar to Redux, in a lot of ways.
Redux is great, and is often the right choice. But, sometimes it adds too much complexity to set up a simple page; As in their todo list example, there's a main index.js
, actions/index.js
, reducers/todo.js
, reducers/visibilityFilter.js
, reducers/index.js
, and finally the presentation components. All for a simple todo.
Federal takes the 'less is more' approach. In any file that uses Federal, you simply need to provide an intial store object, and an object of actions (e.g. actions/index.js
). Then, you can connect()
any component to the store, which will result in it receiving store .props
, including .props.dispatch
for each action method (e.g. this.props.dispatch.setStatus('status')
).
Can I use this in Production?
Of course! It's currently being used, in production, on Conjure.
Setup
npm install --save federal
Use
Simple Example
This example uses Federal to wrap a page content with a centralized store, and then has a child component (<Header />
) connect to the store, which allows it to render the user's name.
pages/dashboard/index.js
import Federal from 'federal';import Header from '../../components/Header'; // assume `account` is passed in as a prop account const initialStore = account ; return <Federal => <Header /> </Federal> ;;
components/Header/index.js
import connect from 'federal'; const Header = account <header> <dl> <dt>User</dt> <dd>accountname</dd> </dl> </header>; // using `connect()` will bind `<Header />` to the full store objectHeader;
Selectors
Let's say the above example's initialStore
changes to something like this:
const initialStore = account products notices;
In this case, you don't want or need products
or notices
in order to render <Header />
. You can use a selector to minimize the scope of the store changes passed to a component. Selectors are passed to connect()
.
const selector = account: storeaccount; selectorHeader;
Actions
Adding actions allows you to dispatch a change to the central store. A dispatch will then ripple and update to any subscribed components.
Actions must return a new object, or Federal will consider nothing to have changed.
pages/dashboard/index.js
import Federal from 'federal';import CountSummary from '../../components/CountSummary';import CountInteractions from '../../components/CountInteractions'import actions from './actions'; const initialStore = count: 0 ; return <Federal = => <CountSummary /> <CountInteractions /> </Federal> ;;
pages/dashboard/actions/index.js
const resetCount = { return Object;}; // second arg to each action is an object, that can be passed when dispatchingconst addToCount = store addition return Object;; resetCount addToCount;
components/CountSummary/index.js
import connect from 'federal'; const CountSummary = count <div>Current count is count</div>; CountSummary;
components/CountInteractions/index.js
import connect from 'federal'; // `connect()` passed a `dispatch` prop that exposes all actions to the componentconst CountInteractions = dispatch <div> <div> <button ='button' = > increment count </button> </div> <div> <button ='button' = > reset count </button> </div> </div>; CountInteractions;
Action Callbacks
Actions have an optional callback.
dispatch;
connect()
Actions via A component may have local actions, while <Federal>
is rendered at a different level in the layout. You can append action handlers to the connected components.
const removeFromCount = store deduction return Object;; // action .removeFromCount() added to CountSummary.props.dispatch,// while still including all root-level actions state removeFromCount CountSummary;