Created
March 9, 2019 05:40
-
-
Save asleepysamurai/bb05df6407d7e6753631ca41e68fac73 to your computer and use it in GitHub Desktop.
TodoContainer useReducer
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
/** | |
* Todo Root Container Component | |
*/ | |
import React, { useReducer, useCallback } from 'react'; | |
import TodoItem from './TodoItem'; | |
import TodoInput from './TodoInput'; | |
const generateID = () => { | |
return Date.now().toString(36) + '-' + (Math.random() + 1).toString(36).substring(7); | |
}; | |
const reducer = (state, action) => { | |
if (action.type === 'toggleItemCompleted') { | |
const { todoItemId } = action; | |
const todoItemIndexInCompletedItemIds = state.completedItemIds.indexOf(todoItemId); | |
const completedItemIds = todoItemIndexInCompletedItemIds === -1 ? | |
state.completedItemIds.concat([todoItemId]) : | |
([ | |
...state.completedItemIds.slice(0, todoItemIndexInCompletedItemIds), | |
...state.completedItemIds.slice(todoItemIndexInCompletedItemIds + 1) | |
]); | |
return { ...state, completedItemIds }; | |
} | |
if (action.type === 'addTodoItem') { | |
const newTodoItem = { | |
text: action.text, | |
id: generateID() | |
}; | |
const todoItems = state.todoItems.concat([newTodoItem]); | |
return { ...state, todoItems }; | |
} | |
return state; | |
}; | |
const initialState = { | |
todoItems: [], | |
completedItemIds: [] | |
}; | |
function Todo() { | |
const [state, dispatch] = useReducer(reducer, initialState); | |
const toggleItemCompleted = useCallback((todoItemId) => { | |
dispatch({ type: 'toggleItemCompleted', todoItemId }); | |
}, [dispatch]); | |
const todoList = state.todoItems.map(todoItem => { | |
return ( | |
<TodoItem | |
key={todoItem.id} | |
completedItemIds={state.completedItemIds} | |
toggleItemCompleted={toggleItemCompleted} | |
{...todoItem} /> | |
); | |
}); | |
const addTodoItem = useCallback((text) => { | |
dispatch({ type: 'addTodoItem', text }); | |
}, [dispatch]); | |
const todoInput = ( | |
<TodoInput | |
onAdd={addTodoItem} /> | |
); | |
return ( | |
<div | |
className="todo-container"> | |
{todoList} | |
{todoInput} | |
</div> | |
); | |
}; | |
export default Todo; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment