-
-
Save justin3737/dda385234dd7960c4644 to your computer and use it in GitHub Desktop.
redux practice
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
//https://egghead.io/lessons/javascript-redux-the-single-immutable-state-tree | |
//redux | |
const createStore = (reducer, initialState) => { | |
let state = initialState; | |
let listeners = []; | |
const getState = () => state; | |
const dispatch = (action) => { | |
state = reducer(state, action); | |
listeners.forEach(listener => listener()); | |
}; | |
const subscribe = (listener) => { | |
listeners.push(listener); | |
return () => { | |
listeners = listeners.filter(l => l !== listener); | |
}; | |
}; | |
return { getState, dispatch, subscribe } | |
}; | |
/*const todoApp = (state = {}, action) => { | |
return { | |
todos: todos(state.todos, action), | |
visibilityFilter: visibilityFilter(state.visibilityFilter, action) | |
} | |
};*/ | |
//const { combineReducers } = Redux; | |
const combineReducers = (reducers) => { | |
return (state = {}, action) => { | |
return Object.keys(reducers).reduce( | |
(nextState, key) => { | |
nextState[key] = reducers[key]( | |
state[key], | |
action | |
); | |
return nextState; | |
}, | |
{} | |
); | |
}; | |
} | |
//------reducer | |
const todo = (state, action) => { | |
switch (action.type) { | |
case 'ADD_TODO': | |
return { | |
id: action.id, | |
text: action.text, | |
completed: false | |
}; | |
case 'TOGGLE_TODO': | |
if (state.id !== action.id) { | |
return state; | |
} | |
return { | |
...state, | |
completed: !state.completed | |
}; | |
default: | |
return state; | |
} | |
}; | |
const todos = (state = [], action) => { | |
switch (action.type) { | |
case 'ADD_TODO': | |
return [ | |
...state, | |
todo(undefined, action) | |
]; | |
case 'TOGGLE_TODO': | |
return state.map(t => todo(t, action)); | |
default: | |
return state; | |
} | |
}; | |
const visibilityFilter = (state = 'SHOW_ALL', action) => { | |
switch (action.type) { | |
case 'SET_VISIBILITY_FILTER': | |
return action.filter; | |
default: | |
return state; | |
} | |
} | |
//---------action | |
let nextTodoId = 0; | |
const addTodo = (text)=> { | |
return { | |
type: 'ADD_TODO', | |
id: nextTodoId++, | |
text | |
}; | |
}; | |
const setVisibilityFilter = (filter) => { | |
return { | |
type: 'SET_VISIBILITY_FILTER', | |
filter | |
}; | |
}; | |
const toggleTodo = (id) => { | |
return { | |
type: 'TOGGLE_TODO', | |
id | |
}; | |
}; | |
const { Component } = React; | |
const { connect } = ReactRedux; | |
//---------AddTodo | |
let AddTodo = ({ dispatch }) => { | |
let input; | |
return ( | |
<div> | |
<input ref={node => { | |
input = node; | |
}} /> | |
<button | |
onClick={() => { | |
dispatch(addTodo(input.value)); | |
input.value = ''; | |
}}> | |
Add Todo | |
</button> | |
</div> | |
); | |
}; | |
AddTodo = connect()(AddTodo); | |
//--------------VisibleTodoList | |
const getVisibleTodos = (todos, filter) => { | |
switch (filter) { | |
case 'SHOW_ALL': | |
return todos; | |
case 'SHOW_COMPLETED': | |
return todos.filter(t => t.completed); | |
case 'SHOW_ACTIVE': | |
return todos.filter(t => !t.completed); | |
} | |
}; | |
const Todo = ({onClick, completed, text}) => ( | |
<li | |
onClick={onClick} | |
style={{ | |
textDecoration: | |
completed ? 'line-through' : 'none' | |
}}> | |
{text} | |
</li> | |
); | |
const TodoList = ({todos, onTodoClick}) => ( | |
<ul> | |
{todos.map(todo => | |
<Todo | |
key ={todo.id} | |
{...todo} | |
onClick={() => onTodoClick(todo.id)}/> | |
)} | |
</ul> | |
); | |
const mapStateToTodoListProps = (state) => { | |
return { | |
todos: getVisibleTodos( | |
state.todos, | |
state.visibilityFilter | |
) | |
}; | |
} | |
const mapDispatchToTodoListProps = (dispatch) => { | |
return { | |
onTodoClick: (id) => { | |
dispatch(toggleTodo(id)); | |
} | |
}; | |
}; | |
const VisibleTodoList = connect( | |
mapStateToTodoListProps, | |
mapDispatchToTodoListProps | |
)(TodoList); | |
//---------footer | |
const Link = ({active, children, onClick}) => { | |
if (active) { | |
return <span>{children}</span>; | |
} | |
return ( | |
<a href='#' | |
onClick={(e) => { | |
e.preventDefault(); | |
onClick(); | |
}} > | |
{children} | |
</a> | |
); | |
}; | |
const Footer = () => ( | |
<p> | |
Show: | |
{''} | |
<FilterLink | |
filter='SHOW_ALL'> | |
All | |
</FilterLink> | |
{','} | |
<FilterLink | |
filter='SHOW_ACTIVE'> | |
Active | |
</FilterLink> | |
{','} | |
<FilterLink | |
filter='SHOW_COMPLETED'> | |
completed | |
</FilterLink> | |
</p> | |
); | |
const mapStateToLinkProps = (state, ownProps) => { | |
return { | |
active: ownProps.filter === state.visibilityFilter | |
}; | |
}; | |
const mapDispatchToLinkProps = (dispatch, ownProps) => { | |
return { | |
onClick: () => { | |
dispatch(setVisibilityFilter(ownProps.filter)); | |
} | |
}; | |
} | |
const FilterLink = connect( | |
mapStateToLinkProps, | |
mapDispatchToLinkProps | |
)(Link); | |
//------Provider | |
class Provider extends Component { | |
getChildContext() { | |
return { | |
store: this.props.store | |
}; | |
} | |
render() { | |
return ( | |
<TodoApp/> | |
); | |
} | |
} | |
Provider.childContextTypes = { | |
store: React.PropTypes.object | |
}; | |
//---------Todo APP | |
const initialState = { | |
todos : [], | |
visibilityFilter: 'SHOW_ALL' | |
} | |
const rootReducers = combineReducers({ | |
todos, | |
visibilityFilter | |
}); | |
const appStore = createStore(rootReducers, initialState); | |
const TodoApp = () => ( | |
<div> | |
<AddTodo /> | |
<VisibleTodoList /> | |
<Footer /> | |
</div> | |
); | |
ReactDOM.render( | |
<Provider store={appStore} />, | |
document.getElementById('root') | |
); |
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"> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/redux/3.0.5/redux.min.js"></script> | |
<script src="//fb.me/react-0.14.3.min.js"></script> | |
<script src="//fb.me/react-dom-0.14.3.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.1/react-redux.min.js"></script> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<div id="root"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment