Skip to content

Instantly share code, notes, and snippets.

@vyorkin
Created March 19, 2016 11:45
Show Gist options
  • Save vyorkin/7e3d6133813c1c649efe to your computer and use it in GitHub Desktop.
Save vyorkin/7e3d6133813c1c649efe to your computer and use it in GitHub Desktop.
just like in redux
import React from 'react';
import { compose, mapProps } from 'recompose';
import { dispatched, logged } from '../enhancers';
import { themeable } from 'fl-core';
import Button from 'fl-button';
import ButtonGroup from 'fl-button-group';
import reducer, { INCREMENT, DECREMENT } from './logic';
import styles from './styles';
const Counter = ({
theme,
counter,
increment,
decrement
}) => (
<div className={theme.counter}>
<span className={theme.value}>{'Count: '}{counter}</span>
<ButtonGroup filled size='small'>
<Button label='+' onClick={increment} />
<Button label='-' onClick={decrement} />
</ButtonGroup>
</div>
);
export const CounterContainer = compose(
logged,
dispatched(reducer, { counter: 0 }),
mapProps(({ dispatch, counter = 0, ...rest }) => ({
increment: () => dispatch({ type: INCREMENT }),
decrement: () => dispatch({ type: DECREMENT }),
dispatch,
counter,
...rest
}))
)(Counter);
export default themeable(CounterContainer, styles);
import { compose, withState, mapProps } from 'recompose';
export default function dispatched(reducer, initialState) {
return WrappedComponent => {
const DispatchedComponent = ({ state, dispatch, ...rest }) => (
<WrappedComponent {...state} {...rest} dispatch={dispatch} />
);
return compose(
withState('state', 'update', initialState),
mapProps(({ dispatch, update, ...rest }) => ({
dispatch: action => update(currentState => {
const newState = reducer(currentState, action);
if (dispatch) dispatch(action);
return newState;
}),
update,
...rest
}))
)(DispatchedComponent);
};
}
import {
compose,
withState,
mapProps,
defaultProps
} from 'recompose';
import dispatched from './dispatched';
export const LOG = 'LOG';
export function reducer(state, action) {
const { type, payload } = action;
if (type === LOG) {
const { log, ...rest } = state;
return {
log: [payload.type, ...log],
...rest
};
}
return state;
}
export default function (WrappedComponent) {
const LoggedComponent = ({ log, ...rest }) => (
<div className='logged'>
<WrappedComponent {...rest} />
<ul className='log'>
{log.map((action, index) =>
<li key={index}>{JSON.stringify(action)}</li>
)}
</ul>
</div>
);
return compose(
dispatched(reducer, { log: [] }),
defaultProps({ log: [] }),
mapProps(({ log, dispatch, ...rest }) => ({
dispatch: action => {
dispatch({ type: LOG, payload: action });
dispatch(action);
},
log,
...rest
}))
)(LoggedComponent);
}
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export default function reducer(state, action) {
const { type } = action;
const { counter, ...rest } = state;
if (type === INCREMENT) {
return { counter: counter + 1, ...rest };
}
if (type === DECREMENT) {
return { counter: counter - 1, ...rest };
}
return state;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment