A store component to quickly initialize state and state handlers in React.
npm install react-senna
import React from "react";
import { Store } from "react-senna";
// describe the state you want in a `seeds` array, for example:
const seeds = [
{
name: "todos",
initialState: [],
}
];
// Use the Store component to initiate React state and setState handlers
const SennaApp = () => (
<Store
seeds={seeds}
render={props => {
console.log(props);
/*
{
todos: []
handlers: {
setTodos: [Function]
}
}
*/
// render whatever you want with the state and handler you just created!
return <App {...props} />;
}}
/>
)
You can easily create more handlers out of the box. Read on!
The Store component accepts the following props: render
, seeds
, withHandlers
, omitHandlers
and flatten
.
Your render function which will receive react-senna
props!
An array of seed objects that will initialize the store, which have the following keys:
The name of the state to be created.
The initial (and reset) value of the state being seeded.
Here, you can create handlers using the current state as a parameter:
const seed = {
name: 'counter',
initialState: 0,
handlers: {
incr: state => state + 1
}
}
/*
results in these props:
{
counter: 0,
handlers: {
setCounter: [Function],
incrCounter: [Function] <-- new handler
}
}
*/
The resulting props.handlers.incrCounter
function increments the counter
state by 1
toggleable: true
will create a handler that will set the state to its opposite:
const seed = {
name: 'isActive',
initialState: false,
toggleable: true
}
/*
results in these props:
{
isActive: false,
handlers: {
setIsActive: [Function],
toggleIsActive: [Function], <-- new handler
}
}
*/
The resulting props.handlers.toggleIsActive
will flip the state of isActive
In fact, toggleable: true
is a shortcut for { handlers: { toggle: state => !state } }
loadable: true
creates an additional loaded state:
const seed = {
name: 'users',
initialState: {},
loadable: true
}
/*
results in these props:
{
users: {},
usersLoaded: false <-- new state
handlers: {
setUsers: [Function],
setUsersLoaded: [Function], <-- new handler
}
}
*/
usersLoaded
is automatically set to true
when users
is updated.
resetable: true
will create a handler that will set the state to its initialState. For example, handlers.resetCounter
.
withHandlers
takes an object of high-order functions.
Here you can access the react-senna
created props so you can you create more complex state changes.
For example, controlling two separate counter states:
const seeds = [
{
name: "counterA",
initialState: 0
},
{
name: "counterB",
initialState: 0
}
];
const withHandlers = {
setAll: ({ handlers }) => num => {
// run multiple handlers
handlers.setCounterA(num);
handlers.setCounterB(num);
}
};
const SennaApp = () => (
<Store
seeds={seeds}
withHandlers={withHandlers}
// use new `props.handlers.setAll` in render:
render={({ handlers, counterA, counterB }) => (
<div>
A: {counterA}
<br />
B: {counterB}
<br />
<button onClick={() => handlers.setAll(10)}>
set all counters to 10
</button>
</div
)}
/>
)
Remove handlers before the props are passed on to the render function. This is good place to remove handlers you used in withHandlers
but don't want to pass forward:
const seeds = [
{
name: "movies",
initialState: {}
}
];
const withHandlers = {
fetchMovies: ({ handlers }) => () => {
// some imaginary db
db.fetchMovies().then(movies => {
handlers.setMovies(movies);
});
}
};
// we want to drop `setMOvies` (and only pass on `fetchMovies`)
const omitHandlers = ["setMovies"];
const SennaApp = () => (
<Store
seeds={seeds}
withHandlers={withHandlers}
omitHandlers={omitHandlers}
render={props => {
console.log(props)
/*
{
movies: {}
handlers: { <-- without `setMovies`
fetchMovies: [Function]
}
}
do as you please with the props:
*/
return <MyApp {...props} />;
}}
/>
)
default: false
If you don't like the handlers
key you don't have to use it:
const seeds = [
{
name: "movies",
initialState: {}
}
];
const SennaApp = () => (
<Store
seeds={seeds}
flatten={true}
render={props => {
console.log(props)
/*
{
movies: {},
setMovies: [Function] <-- without the `handlers` key
}
*/
return <MyApp {...props} />;
}}
/>
);
- Andrew Clark's recompose library
- Kent C. Dodds Advanced React Component Patterns Egghead course
- Never Write Another HOC talk by Michael Jackson