Here is a clickable React Component:
0
renders: 1
Each one will be connected to a part of the store, and display:
You see the exact same behaviour as using a local useState()
, except this state is not local: it's part of an external global state handled by La Taverne
.
To read the click count, we pour
the value from the store:
/* src/features/single-square/container.js */
import {useTaverne} from 'taverne/hooks';
const {pour} = useTaverne();
const clickCount = pour('singleSquare.clickCount');
To reduce a new state from an action, we use this reaction
:
/* src/features/single-square/reducer.js */
const reaction = {
on: TOGGLE_SINGLE_SQUARE,
reduce: (state, payload) => {
state.clickCount++;
}
};
To enable useTaverne
and pour
hooks, we need to instanciate La Taverne
for our <App/>
import React from 'react';
import {render} from 'react-dom';
import createLaTaverne from 'taverne';
import {Taverne} from 'taverne/hooks';
import singleSquare from './features/single-square/reducer';
const {dispatch, store} = createLaTaverne({singleSquare});
render(
<Taverne dispatch={dispatch} store={store}>
<App />
</Taverne>,
container
);
Let's illustrate how local rendering with the pour
hook is efficient on nested state properties.
We'll use 4 separated parts in our global state, connected to dedicated containers:
singleSquare
to count the clicks for the <SingleSquare/>
singleRGB
to count the clicks for the <SingleRGB/>
singlePack
to count the clicks for the <SinglePack/>
multiPacks
to count the clicks for the <MultiPacks/>
Now let's nest some Squares
composed of 3 Squares
, colored R
,G
,B
const {color} = props;
const {pour} = useTaverne();
const clickCount = pour(`singleRGB.${color}`);
0
renders: 1
0
renders: 1
0
renders: 1
composed of many <RGB/>
const {color, num: rgbNum} = props;
const {pour} = useTaverne();
const clickCount = pour(`singlePack.${rgbNum}.${color}`);
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
const {color, packNum, rgbNum} = props;
const {pour} = useTaverne();
const clickCount = pour(`multiPacks.${packNum}.${rgbNum}.${color}`);
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
Now let's instanciate twice this <App/>
, side by side.
<>
<DemoApp />
<DemoApp />
</>
<Taverne/>
provides with properly scoped stores:
const DemoApp = props => {
const {dispatch, store} = createLaTaverne({
singlePack,
singleRGB,
singleSquare,
multiPacks
});
return (
<Taverne dispatch={dispatch} store={store}>
<App />
</Taverne>
);
};
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1
0
renders: 1