반응형
수정하기 구현은 전편 삭제하기와 비슷합니다. 내장함수 map을 이용하여 onToggle함수를 작성하고 App->TodoList->TodoListItem순으로 전달해줍니다.
onToggle
import React, { useState, useRef, useCallback } from "react";
import TodoInsert from "./components/TodoInsert/TodoInsert";
import TodoList from "./components/TodoList/TodoList";
import TodoTemplate from "./components/TodoTemplate/TodoTemplate";
const App = () => {
const [todos, setTodos] = useState([]);
const nextId = useRef(0);
const onInsert = useCallback(
(text) => {
const todo = { id: nextId.current, text, checked: false };
setTodos(todos.concat(todo));
nextId.current += 1;
},
[todos]
);
const onRemove = useCallback(
(id) => {
setTodos(todos.filter((todo) => todo.id !== id));
},
[todos]
);
const onToggle = useCallback(
(id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, checked: !todo.checked } : todo
)
);
},
[todos]
);
return (
<TodoTemplate>
<TodoInsert onInsert={onInsert} />
<TodoList todos={todos} onRemove={onRemove} onToggle={onToggle} />
</TodoTemplate>
);
};
export default App;
map을 이용하여 todos안에 투두객체중 특정 id값을 가지고 있는 투두의 checked값을 반전시켜줍니다. 파라미터로 사용된 id값이 todo.id와 같을경우 새로운 객체를 생성, 다를경우 처음 상태 그대로 반환합니다. (todo.id===id ? .. : .. ). 즉, todos배열에서 변화가 필요한 원소만 업데이트되고 나머지는 그대로 남게됩니다(새로운 배열 생성X).
TodoList.js
import React from "react";
import TodoListItem from "../TodoListItem/TodoListItem";
import { ToDoList } from "./TodoList.styles";
const TodoList = ({ todos, onRemove, onToggle }) => {
return (
<ToDoList>
{todos.map((todo) => (
<TodoListItem todo={todo} key={todo.id} onRemove={onRemove} onToggle={onToggle} />
))}
</ToDoList>
);
};
export default TodoList;
App에서 받은 onToggle을 그대로 TodoListItem에 전달합니다.
TodoListItem.js
import React from "react";
import {
MdCheckBox,
MdCheckBoxOutlineBlank,
MdRemoveCircleOutline,
} from "react-icons/md";
import "./TodoListItem.styles";
import {
CheckBox,
Remove,
ToDoListItem,
ToDoText,
} from "./TodoListItem.styles";
const TodoListItem = ({ todo, onRemove, onToggle }) => {
const { id, text, checked } = todo;
return (
<ToDoListItem>
<CheckBox onClick={() => onToggle(id)} checked={checked}>
{checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
<ToDoText>{text}</ToDoText>
</CheckBox>
<Remove onClick={() => onRemove(id)}>
<MdRemoveCircleOutline />
</Remove>
</ToDoListItem>
);
};
export default TodoListItem;
TodoListItem.styles.js
(...)
export const CheckBox = styled.div`
cursor: pointer;
flex: 1;
display: flex;
align-items: center;
svg {
font-size: 1.5rem;
}
${(props) =>
props.checked &&
css`
color: #adb5bd;
text-decoration: line-through;
svg{
color: #22b8cf};
}
`}
`;
(...)
checked값을 props으로 받아와 스타일을 완성시켜 줍니다.
$ yarn start
반응형
'리액트 React > 투두앱 만들기' 카테고리의 다른 글
투두앱 만들기 4: 투두 삭제하기 (0) | 2021.02.11 |
---|---|
투두앱 만들기 3: 투두 추가하기 (0) | 2021.02.10 |
투두앱 만들기 2: TodoInsert, TodoList, TodoListItem (0) | 2021.02.10 |
투두앱 만들기 1: TodoTemplate (0) | 2021.02.05 |