Created
March 9, 2019 05:43
-
-
Save asleepysamurai/6e1893cc014c32e7f06e4129a9e45451 to your computer and use it in GitHub Desktop.
TodoContainer Function Component
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: [] | |
}; | |
const initState = (state) => { | |
let savedTodos = localStorage.getItem('todos'); | |
try { | |
savedTodos = JSON.parse(savedTodos); | |
return Object.assign({}, state, savedTodos); | |
} catch (err) { | |
console.log('Saved todos non-existent or corrupt. Trashing saved todos.'); | |
return state; | |
} | |
}; | |
function Todo() { | |
const [state, dispatch] = useReducer(reducer, initialState, initState); | |
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