Skip to content

Instantly share code, notes, and snippets.

@asleepysamurai
Created March 9, 2019 05:42
Show Gist options
  • Save asleepysamurai/2498b36f1561ec597fa0df5b333450a4 to your computer and use it in GitHub Desktop.
Save asleepysamurai/2498b36f1561ec597fa0df5b333450a4 to your computer and use it in GitHub Desktop.
TodoContainer useEffect
/**
* 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