-
-
Save martenbiehl/bf081d38d75e2115ab24de7e01dfee13 to your computer and use it in GitHub Desktop.
Simple redux example based on Dan Abramovs Egghead.io course JS Bin// source http://jsbin.com/yoxejalali
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<pre id="app"></pre> | |
<script id="jsbin-javascript"> | |
// ACTION STRINGS | |
"use strict"; | |
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } | |
var ADD_TODO = "ADD_TODO"; | |
var REMOVE_TODO = "REMOVE_TODO"; | |
var SELECT_TODO = "SELECT_TODO"; | |
// REDUCERS | |
var todoReducer = function todoReducer(state, action) { | |
switch (action.type) { | |
case ADD_TODO: | |
return Object.assign({ | |
id: undefined, | |
name: undefined, | |
completed: false | |
}, action.payload); | |
} | |
}; | |
var selectReducer = function selectReducer(state, action) { | |
switch (action.type) { | |
case SELECT_TODO: | |
return action.payload.id; | |
} | |
return state; | |
}; | |
var todosReducer = function todosReducer(state, action) { | |
if (state === undefined) state = []; | |
console.log("ACTION FIRED", action); | |
switch (action.type) { | |
case ADD_TODO: | |
return [].concat(_toConsumableArray(state), [todoReducer(undefined, action)]); | |
case REMOVE_TODO: | |
var index = state.findIndex(function (element) { | |
return element.id === action.payload.id; | |
}); | |
return [].concat(_toConsumableArray(state.slice(0, index)), _toConsumableArray(state.slice(index + 1))); | |
} | |
return state; | |
}; | |
// SIMPLIFIED REDUX (shamelessly ripped off) | |
var combineReducers = function combineReducers(reducers) { | |
return function (state, action) { | |
if (state === undefined) state = {}; | |
return Object.keys(reducers).reduce(function (nextState, key) { | |
nextState[key] = reducers[key](state[key], action); | |
return nextState; | |
}, {}); | |
}; | |
}; | |
var createStore = function createStore(reducer) { | |
var state = undefined; | |
var listeners = []; | |
var getState = function getState() { | |
return state; | |
}; | |
var dispatch = function dispatch(action) { | |
state = reducer(state, action); | |
listeners.forEach(function (listener) { | |
return listener(); | |
}); | |
}; | |
var subscribe = function subscribe(listener) { | |
listeners.push(listener); | |
}; | |
dispatch({}); | |
return { | |
getState: getState, | |
dispatch: dispatch, | |
subscribe: subscribe | |
}; | |
}; | |
// WIRING UP | |
var app = combineReducers({ | |
todos: todosReducer, | |
selected: selectReducer | |
}); | |
var store = createStore(app); | |
var render = function render() { | |
return console.log(store.getState()); | |
}; | |
// "render" yeah, right | |
// but e.g. | |
// | |
// let root = document.querySelector('#app') | |
// let renderOneTodo = (todo) => { | |
// let todoName = document.createTextNode(todo.name+"\n") | |
// root.appendChild(todoName) | |
// } | |
// let todoRender = () => { | |
// store.getState()['todos'].forEach(renderOneTodo) | |
// } | |
store.subscribe(render); | |
// LETS DO STUFF | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 0, | |
name: 'test redux' | |
} | |
}); | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 1, | |
name: 'read more about observables' | |
} | |
}); | |
store.dispatch({ | |
type: SELECT_TODO, | |
payload: { | |
id: 0 | |
} | |
}); | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript"> | |
// ACTION STRINGS | |
const ADD_TODO = "ADD_TODO" | |
const REMOVE_TODO = "REMOVE_TODO" | |
const SELECT_TODO = "SELECT_TODO" | |
// REDUCERS | |
const todoReducer = (state, action) => { | |
switch (action.type) { | |
case ADD_TODO: | |
return Object.assign({ | |
id: undefined, | |
name: undefined, | |
completed: false | |
}, action.payload) | |
} | |
} | |
const selectReducer = (state, action) => { | |
switch (action.type) { | |
case SELECT_TODO: | |
return action.payload.id | |
} | |
return state; | |
} | |
const todosReducer = (state = [], action) => { | |
console.log("ACTION FIRED", action) | |
switch (action.type) { | |
case ADD_TODO: | |
return [ | |
...state, | |
todoReducer(undefined, action) | |
] | |
case REMOVE_TODO: | |
const index = state.findIndex( (element) => element.id === action.payload.id) | |
return [ | |
...state.slice(0, index), | |
...state.slice(index + 1) | |
] | |
} | |
return state | |
} | |
// SIMPLIFIED REDUX (shamelessly ripped off) | |
const combineReducers = (reducers) => { | |
return (state = {}, action) => { | |
return Object.keys(reducers) | |
.reduce( | |
(nextState, key) => { | |
nextState[key] = reducers[key]( | |
state[key], | |
action | |
) | |
return nextState | |
}, | |
{} | |
) | |
} | |
} | |
const createStore = (reducer) => { | |
let state | |
let listeners = [] | |
const getState = () => state | |
const dispatch = (action) => { | |
state = reducer(state, action) | |
listeners.forEach(listener => listener()) | |
} | |
const subscribe = (listener) => { | |
listeners.push(listener) | |
} | |
dispatch({}) | |
return { | |
getState: getState, | |
dispatch: dispatch, | |
subscribe: subscribe | |
} | |
} | |
// WIRING UP | |
const app = combineReducers({ | |
todos: todosReducer, | |
selected: selectReducer | |
}) | |
let store = createStore(app) | |
let render = () => console.log(store.getState()) | |
// "render" yeah, right | |
// but e.g. | |
// | |
// let root = document.querySelector('#app') | |
// let renderOneTodo = (todo) => { | |
// let todoName = document.createTextNode(todo.name+"\n") | |
// root.appendChild(todoName) | |
// } | |
// let todoRender = () => { | |
// store.getState()['todos'].forEach(renderOneTodo) | |
// } | |
store.subscribe(render) | |
// LETS DO STUFF | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 0, | |
name: 'test redux' | |
} | |
}) | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 1, | |
name: 'read more about observables' | |
} | |
}) | |
store.dispatch({ | |
type: SELECT_TODO, | |
payload: { | |
id: 0 | |
} | |
})</script></body> | |
</html> |
This file contains hidden or 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
// ACTION STRINGS | |
"use strict"; | |
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } | |
var ADD_TODO = "ADD_TODO"; | |
var REMOVE_TODO = "REMOVE_TODO"; | |
var SELECT_TODO = "SELECT_TODO"; | |
// REDUCERS | |
var todoReducer = function todoReducer(state, action) { | |
switch (action.type) { | |
case ADD_TODO: | |
return Object.assign({ | |
id: undefined, | |
name: undefined, | |
completed: false | |
}, action.payload); | |
} | |
}; | |
var selectReducer = function selectReducer(state, action) { | |
switch (action.type) { | |
case SELECT_TODO: | |
return action.payload.id; | |
} | |
return state; | |
}; | |
var todosReducer = function todosReducer(state, action) { | |
if (state === undefined) state = []; | |
console.log("ACTION FIRED", action); | |
switch (action.type) { | |
case ADD_TODO: | |
return [].concat(_toConsumableArray(state), [todoReducer(undefined, action)]); | |
case REMOVE_TODO: | |
var index = state.findIndex(function (element) { | |
return element.id === action.payload.id; | |
}); | |
return [].concat(_toConsumableArray(state.slice(0, index)), _toConsumableArray(state.slice(index + 1))); | |
} | |
return state; | |
}; | |
// SIMPLIFIED REDUX (shamelessly ripped off) | |
var combineReducers = function combineReducers(reducers) { | |
return function (state, action) { | |
if (state === undefined) state = {}; | |
return Object.keys(reducers).reduce(function (nextState, key) { | |
nextState[key] = reducers[key](state[key], action); | |
return nextState; | |
}, {}); | |
}; | |
}; | |
var createStore = function createStore(reducer) { | |
var state = undefined; | |
var listeners = []; | |
var getState = function getState() { | |
return state; | |
}; | |
var dispatch = function dispatch(action) { | |
state = reducer(state, action); | |
listeners.forEach(function (listener) { | |
return listener(); | |
}); | |
}; | |
var subscribe = function subscribe(listener) { | |
listeners.push(listener); | |
}; | |
dispatch({}); | |
return { | |
getState: getState, | |
dispatch: dispatch, | |
subscribe: subscribe | |
}; | |
}; | |
// WIRING UP | |
var app = combineReducers({ | |
todos: todosReducer, | |
selected: selectReducer | |
}); | |
var store = createStore(app); | |
var render = function render() { | |
return console.log(store.getState()); | |
}; | |
// "render" yeah, right | |
// but e.g. | |
// | |
// let root = document.querySelector('#app') | |
// let renderOneTodo = (todo) => { | |
// let todoName = document.createTextNode(todo.name+"\n") | |
// root.appendChild(todoName) | |
// } | |
// let todoRender = () => { | |
// store.getState()['todos'].forEach(renderOneTodo) | |
// } | |
store.subscribe(render); | |
// LETS DO STUFF | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 0, | |
name: 'test redux' | |
} | |
}); | |
store.dispatch({ | |
type: ADD_TODO, | |
payload: { | |
id: 1, | |
name: 'read more about observables' | |
} | |
}); | |
store.dispatch({ | |
type: SELECT_TODO, | |
payload: { | |
id: 0 | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment