Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.27 KB | None | 0 0
  1. // action creators
  2. let nextTodoId = 0;
  3. const addTodo = (text) => ({
  4. type: 'ADD_TODO',
  5. id: nextTodoId++,
  6. text
  7. });
  8.  
  9. const setVisibilityFilter = (filter) => ({
  10. type: 'SET_VISIBILITY_FILTER',
  11. filter
  12. });
  13.  
  14. const toggleTodo = (id) => ({
  15. type: 'TOGGLE_TODO',
  16. id
  17. });
  18.  
  19. // reducers
  20. const todo = (state, action) => {
  21. switch(action.type) {
  22. case 'ADD_TODO':
  23. return {
  24. id: action.id,
  25. text: action.text,
  26. completed: false
  27. };
  28. case 'TOGGLE_TODO':
  29. return Object.assign({}, state, {completed: !state.completed});
  30. default:
  31. return state;
  32. }
  33. }
  34.  
  35. const todos = (state = [], action) => {
  36. switch(action.type) {
  37. case 'ADD_TODO':
  38. return [
  39. ...state,
  40. todo(undefined, action)
  41. ]
  42. case 'TOGGLE_TODO':
  43. return state.map((t) => t.id !== action.id ? t : todo(t, action));
  44. default:
  45. return state;
  46. }
  47. };
  48.  
  49. const visibilityFilter = (state = 'SHOW_ALL', action) => {
  50. switch(action.type) {
  51. case 'SET_VISIBILITY_FILTER':
  52. return action.filter;
  53. default:
  54. return state;
  55. }
  56. };
  57.  
  58. const testAddTodo = () => {
  59. const action = {
  60. type: 'ADD_TODO',
  61. id: 0,
  62. text: 'Write puns'
  63. };
  64. const beforeState = [];
  65. const afterState = [
  66. {
  67. id: 0,
  68. text: 'Write puns',
  69. completed: false
  70. }
  71. ];
  72.  
  73. expect(todos(beforeState, action)).toEqual(afterState);
  74. };
  75.  
  76. const testToggleTodo = () => {
  77. const action = {
  78. type: 'TOGGLE_TODO',
  79. id: 1
  80. };
  81. const beforeState = [
  82. {
  83. id: 0,
  84. text: 'Write puns',
  85. completed: false
  86. }, {
  87. id: 1,
  88. text: 'do the reduxes',
  89. completed: false
  90. }
  91. ];
  92. const afterState = [
  93. {
  94. id: 0,
  95. text: 'Write puns',
  96. completed: false
  97. }, {
  98. id: 1,
  99. text: 'do the reduxes',
  100. completed: true
  101. }
  102. ];
  103.  
  104. expect(todos(beforeState, action)).toEqual(afterState);
  105. };
  106.  
  107. const getVisibleTodos = (todos, filter) => {
  108. switch (filter) {
  109. case 'SHOW_ACTIVE':
  110. return todos.filter(t => !t.completed);
  111. case 'SHOW_COMPLETED':
  112. return todos.filter(t => t.completed);
  113. case 'SHOW_ALL':
  114. default:
  115. return todos;
  116. }
  117. }
  118.  
  119. testAddTodo();
  120. testToggleTodo();
  121.  
  122. console.log('tests passed');
  123.  
  124. const { Component } = React;
  125. const { createStore, combineReducers } = Redux;
  126. const { connect, Provider } = ReactRedux;
  127. const reducers = Redux.combineReducers({
  128. todos, visibilityFilter
  129. });
  130.  
  131. let AddTodo = ({ onAddTodoClick }) => {
  132. let input;
  133. return (
  134. <div>
  135. <input ref={node => input = node} />
  136. <button onClick={() => {
  137. onAddTodoClick(input.value);
  138. input.value = '';
  139. }}>
  140. Add Todo
  141. </button>
  142. </div>
  143. );
  144. };
  145. AddTodo = connect(
  146. null,
  147. dispatch => ({
  148. onAddTodoClick: text => dispatch(addTodo(text))
  149. })
  150. )(AddTodo);
  151.  
  152. const Link = ({ active, children, onClick }) => {
  153. if (active) {
  154. return <span>{children}</span>
  155. }
  156.  
  157. return (
  158. <a href='#' onClick={e => {
  159. e.preventDefault();
  160. onClick();
  161. }}>{children}</a>
  162. );
  163. }
  164.  
  165. const FilterLink = connect(
  166. (state, props) => ({
  167. active: props.filter === state.visibilityFilter
  168. }),
  169. (dispatch, props) => ({
  170. onClick: () => dispatch(setVisibilityFilter(props.filter))
  171. })
  172. )(Link);
  173.  
  174. const Footer = () => {
  175. return (
  176. <p>
  177. {'Show: '}
  178. <FilterLink filter='SHOW_ALL'>All</FilterLink>{' '}
  179. <FilterLink filter='SHOW_ACTIVE'>Active</FilterLink>{' '}
  180. <FilterLink filter='SHOW_COMPLETED'>Completed</FilterLink>{' '}
  181. </p>
  182. )
  183. };
  184.  
  185. const Todo = ({ onClick, completed, text }) => {
  186. return (
  187. <li onClick={onClick}
  188. style={{textDecoration: completed ? 'line-through' : 'none'}}
  189. >
  190. {text}
  191. </li>
  192. )
  193. };
  194.  
  195. const TodoList = ({todos, onTodoClick}) => {
  196. return (
  197. <ul>
  198. {todos.map(t =>
  199. <Todo
  200. key={t.id}
  201. {...t}
  202. onClick={() => onTodoClick(t.id)} />
  203. )}
  204. </ul>
  205. )
  206. };
  207.  
  208. const VisibleTodoList = connect(
  209. state => ({
  210. todos: getVisibleTodos(state.todos, state.visibilityFilter)
  211. }),
  212. dispatch => ({
  213. onTodoClick: (id) => dispatch(toggleTodo(id))
  214. })
  215. )(TodoList);
  216.  
  217. const TodoApp = () => (
  218. <div>
  219. <AddTodo />
  220. <VisibleTodoList />
  221. <Footer />
  222. </div>
  223. );
  224.  
  225. ReactDOM.render(
  226. <Provider store={createStore(reducers)}>
  227. <TodoApp />
  228. </Provider>,
  229. document.getElementById('root')
  230. );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement