Skip to content

Instantly share code, notes, and snippets.

@jmlavoier
Created July 12, 2017 00:03
Show Gist options
  • Save jmlavoier/cce5c6cb227cbed1057dc60f963d1656 to your computer and use it in GitHub Desktop.
Save jmlavoier/cce5c6cb227cbed1057dc60f963d1656 to your computer and use it in GitHub Desktop.
Redux lesson 18
//CDNs
//https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js
//https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.js
//https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js
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({}, 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;
}
};
const FilterLink = ({ filter, currentFilter, onClick, children }) => {
if (filter === currentFilter) {
return <span>{children}</span>;
}
return (
<a href='#'
onClick={e => {
e.preventDefault();
onClick(filter);
}}
>{children}</a>
);
}
const Footer = ({ visibilityFilter, onFilterClick }) => (
<p>
Show:
{' '} <FilterLink filter='SHOW_ALL'
currentFilter={visibilityFilter}
onClick={onFilterClick}
>All</FilterLink>
{' '} <FilterLink filter='SHOW_ACTIVE'
currentFilter={visibilityFilter}
onClick={onFilterClick}
>Active</FilterLink>
{' '} <FilterLink filter='SHOW_COMPLETED'
currentFilter={visibilityFilter}
onClick={onFilterClick}
>Completed</FilterLink>
</p>
)
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 AddTodo = ({ onAddClick }) => {
let input;
return (
<div>
<input ref={node => { input = node;}} />
<button onClick={() => {
onAddClick(input.value);
input.value = '';
}}>
Add Todo
</button>
</div>
);
};
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 { combineReducers } = Redux;
const todoApp = combineReducers({
todos,
visibilityFilter
});
const { createStore } = Redux;
const store = createStore(todoApp);
const { Component } = React;
let nextTodoId = 0;
const TodoApp = ({ todos, visibilityFilter }) => (
<div>
<AddTodo onAddClick={text =>
store.dispatch({
type: 'ADD_TODO',
id: nextTodoId++,
text
})
}
/>
<TodoList todos={getVisibleTodos(todos, visibilityFilter)}
onTodoClick={id =>
store.dispatch({
type: 'TOGGLE_TODO',
id
})
}
/>
<Footer visibilityFilter={visibilityFilter}
onFilterClick={filter => {
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter
});
}}
/>
</div>
);
const render = () => {
ReactDOM.render(
<TodoApp {...store.getState()} />,
document.getElementById("root")
);
};
store.subscribe(render);
render();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment