Skip to content

Instantly share code, notes, and snippets.

@MegaBlackLabel
Forked from joeporpeglia/Counter.jsx
Created February 7, 2018 02:59
Show Gist options
  • Save MegaBlackLabel/1f580f533d7856e1f768fb604f164ae2 to your computer and use it in GitHub Desktop.
Save MegaBlackLabel/1f580f533d7856e1f768fb604f164ae2 to your computer and use it in GitHub Desktop.
Redux as a Render Prop
import StoreProvider from './StoreProvider';
const increment = { type: '@counter/increment' };
const decrement = { type: '@counter/decrement' };
const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
switch (action.type) {
case increment.type:
return {
count: state.count + 1,
};
case decrement.type:
return {
cound: state.count - 1,
};
}
return state;
}
export default () => (
<StoreProvider
reducer={reducer}
render={({ state, dispatch }) => (
<div>
<h1>Count: {state.count}</h1>
<button onClick={() => dispatch(increment)}>Increment</button>
<button onClick={() => dispatch(decrement)}>Decrement</button>
</div>
)}
/>
)
import React from 'react';
export default class StoreProvider extends React.Component {
constructor(props) {
super(props);
this.dispatch = this.createDispatch(props.reducer);
this.state = props.reducer(this.state, { type: '@store/init' });
}
createDispatch(reducer) {
return (action) => {
const state = reducer(this.state, action);
this.setState(() => state);
return state;
};
}
componentWillReceiveProps({ reducer }) {
if (reducer !== this.props.reducer) {
this.dispatch = this.createDispatch(reducer);
}
}
render() {
return this.props.render({
dispatch: this.dispatch,
state: this.state,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment