Created
December 23, 2015 07:16
-
-
Save davorbadrov/acd534bb477350352919 to your computer and use it in GitHub Desktop.
Simple React/Redux example, taken from Dan Abramov's Redux tutorial series on Egghead.io
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
import expect from 'expect'; | |
import { createStore } from 'redux'; | |
/** | |
* The reducer function which takes a state and action, | |
* returns the new state | |
* | |
* @param {Number} state old state from the store | |
* @param {Object} action action which is run to update the store | |
* @return {Number} updated store state | |
*/ | |
const counter = (state = 0, action) => { | |
switch (action.type) { | |
case 'INCREMENT': | |
return state + 1; | |
case 'DECREMENT': | |
return state - 1; | |
default: | |
return state; | |
} | |
}; | |
// A simple create store implementation similar to react | |
// | |
// /** | |
// * Method takes a reducer function and returns an object | |
// * which exposes getState, dispatch and subscribe methods | |
// * | |
// * @param {Function} reducer a reducer method which returns updated state | |
// * @return {Object} created store object which contains getState, dispatch and subscribe methods | |
// */ | |
// const createStore = (reducer) => { | |
// let state; // holds the state | |
// let listeners = []; // holds reference to the added listeners | |
// | |
// // method returns state | |
// const getState = () => state; | |
// | |
// // methods enables callback subscribing | |
// // returns unsubscribe method | |
// const subscribe = (listener) => { | |
// listeners.push(listener); | |
// return () => { | |
// listeners = listeners.filter((l) => l !== listener); | |
// }; | |
// }; | |
// | |
// // method triggers the reducer and listener update | |
// const dispatch = (action) => { | |
// state = reducer(state, action); | |
// listeners.forEach(listener => listener()); | |
// }; | |
// | |
// // trigger dispatch once to set the state to default | |
// dispatch({}); | |
// | |
// // expose the object w/ methods | |
// return {getState, dispatch, subscribe}; | |
// }; | |
// create a store with counter reducer | |
const store = createStore(counter); | |
// Component which we'll render (Uses React internally) | |
const Counter = ({value, onIncrement, onDecrement}) => ( | |
<div> | |
<h1>{value}</h1> | |
<button onClick={onIncrement}>+</button> | |
<button onClick={onDecrement}>-</button> | |
</div> | |
); | |
// Render method, renders the Counter to the DOM | |
const render = () => { | |
ReactDOM.render( | |
<Counter value={store.getState()} | |
onIncrement={() => | |
store.dispatch({ | |
type: 'INCREMENT' | |
}) | |
} | |
onDecrement={() => | |
store.dispatch({ | |
type: 'DECREMENT' | |
}) | |
} />, | |
document.getElementById('root') | |
); | |
}; | |
// subscribe to store changes | |
// set render as callback | |
store.subscribe(render); | |
// trigger it once to render initialy | |
render(); | |
// added some tests for the store | |
expect( | |
counter(0, {type: 'INCREMENT'}) | |
).toEqual(1); | |
expect( | |
counter(1, {type: 'INCREMENT'}) | |
).toEqual(2); | |
expect( | |
counter(2, {type: 'DECREMENT'}) | |
).toEqual(1); | |
expect( | |
counter(1, {type: 'DECREMENT'}) | |
).toEqual(0); | |
expect( | |
counter(1, {type: 'WHATEVER'}) | |
).toEqual(1); | |
expect( | |
counter(undefined, {}) | |
).toEqual(0); | |
// we'll get here only if all tests pass | |
console.log('tests passed'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment