import React, { useState, useRef, useEffect } from "react"; import Form from "./components/Form"; import FilterButton from "./components/FilterButton"; import Todo from "./components/Todo"; import { nanoid } from "nanoid"; function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; } const FILTER_MAP = { All: () => true, Active: task => !task.completed, Completed: task => task.completed }; const FILTER_NAMES = Object.keys(FILTER_MAP); function App(props) { const [tasks, setTasks] = useState(props.tasks); const [filter, setFilter] = useState('All'); function toggleTaskCompleted(id) { const updatedTasks = tasks.map(task => { // if this task has the same ID as the edited task if (id === task.id) { // use object spread to make a new obkect // whose `completed` prop has been inverted return {...task, completed: !task.completed} } return task; }); setTasks(updatedTasks); } function deleteTask(id) { const remainingTasks = tasks.filter(task => id !== task.id); setTasks(remainingTasks); } function editTask(id, newName) { const editedTaskList = tasks.map(task => { // if this task has the same ID as the edited task if (id === task.id) { // return {...task, name: newName} } return task; }); setTasks(editedTaskList); } const taskList = tasks .filter(FILTER_MAP[filter]) .map(task => ( )); const filterList = FILTER_NAMES.map(name => ( )); function addTask(name) { const newTask = { id: "todo-" + nanoid(), name: name, completed: false }; setTasks([...tasks, newTask]); } const tasksNoun = taskList.length !== 1 ? 'tasks' : 'task'; const headingText = `${taskList.length} ${tasksNoun} remaining`; const listHeadingRef = useRef(null); const prevTaskLength = usePrevious(tasks.length); useEffect(() => { if (tasks.length - prevTaskLength === -1) { listHeadingRef.current.focus(); } }, [tasks.length, prevTaskLength]); return (
{filterList}

{headingText}

    {taskList}
); } export default App;