Created
March 9, 2019 05:42
-
-
Save asleepysamurai/2498b36f1561ec597fa0df5b333450a4 to your computer and use it in GitHub Desktop.
TodoContainer useEffect
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, useEffect } 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); | |
useEffect(() => { | |
localStorage.setItem('todos', JSON.stringify(state)); | |
}); | |
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