먼저 React의 CRUD에 대해 알아보겠다.
CRUD 란?
CRUD는 리액트를 사용하여 기본적인 데이터 운영 기능을 구현하는 것을 말한다. 다음 네 가지 기본 데이터베이스 운영을 나타낸다.
- Create(생성): 새로운 데이터를 만들고 추가하는 기능
- Read(읽기): 기존 데이터를 조회하고 표시하는 기능
- Update(갱신): 기존 데이터를 수정하는 기능
- Delete(삭제): 기존 데이터를 제거하는 기능
오늘은 TodoList에 Update를 추가해보겠다!
업데이트에 필요한 요소는 Read(현재 값을 가져와야 함)와 Create(현재 값 위에 덮어 씌어야 함)이다.
forEach와 map의 차이
forEach :
- forEach는 배열을 순회하면서 각 요소를 처리하지만, 새로운 배열은 반환하지 않는다. 직접 새로운 배열을 만들어야 하는 상황에서 유용하다.
- 일반적으로 상태 업데이트보다는 부수 효과(side effect)가 필요한 경우에 사용된다.
map :
- map은 각 요소를 반환하여 새로운 배열은 반환한다. 상태 업데이트 시 기존 배열을 수정하여 새로운 배열을 만드는데 적합하다.
- 리액트에서 상태 관리 시 map을 사용하는 것이 더 직관적이며, 코드가 간결해지는 경향이 있다.
Update 실습!!
forEach 사용법
const handleUpdate = (id) => {
// 1. 새로운 배열을 만들 빈 배열을 선언합니다.
const updatedTodos = [];
// 2. todos 배열의 각 항목을 순회합니다.
todos.forEach((todo) => {
// 3. 현재 항목의 id가 수정하려는 id와 일치하는지 확인합니다.
if (todo.id === id) {
// 4. id가 일치하면 completed 상태를 반전시킨 새로운 항목을 생성합니다.
const updatedTodo = {
id: todo.id, // 기존 id 유지
text: todo.text, // 기존 텍스트 유지
completed: !todo.completed // completed 상태를 반전시킴
};
// 5. 수정된 항목을 새로운 배열에 추가합니다.
updatedTodos.push(updatedTodo);
} else {
// 6. id가 일치하지 않으면 기존 항목을 그대로 배열에 추가합니다.
updatedTodos.push(todo);
}
});
// 7. 상태를 새로운 배열로 업데이트합니다.
setTodos(updatedTodos);
};
map 사용법
const handleUpdate = (id) => {
// 1. todos 배열의 각 항목을 순회하고, 수정된 항목을 반환하여 새로운 배열을 만듭니다.
const updatedTodos = todos.map((todo) => {
// 2. 현재 항목의 id가 수정하려는 id와 일치하는지 확인합니다.
if (todo.id === id) {
// 3. id가 일치하면 completed 상태를 반전시킨 새로운 항목을 반환합니다.
return {
id: todo.id, // 기존 id 유지
text: todo.text, // 기존 텍스트 유지
completed: !todo.completed // completed 상태를 반전시킴
};
} else {
// 4. id가 일치하지 않으면 기존 항목을 그대로 반환합니다.
return todo;
}
});
// 5. 상태를 새로운 배열로 업데이트합니다.
setTodos(updatedTodos);
};
prev 사용법
const handleUpdate = (id) => {
// 1. setTodos 함수를 호출하여 todos 상태를 업데이트합니다.
setTodos((prevTodos) =>
// 2. prevTodos 배열을 순회하면서 새로운 배열을 생성합니다.
prevTodos.map((todo) =>
// 3. 현재 todo의 id가 매개변수로 받은 id와 일치하는지 확인합니다.
todo.id === id
// 4. 일치한다면, 해당 todo 객체의 completed 속성을 반전시킵니다.
? { ...todo, completed: !todo.completed }
// 5. 일치하지 않는다면, 원래 todo 객체를 그대로 반환합니다.
: todo
)
);
};
리액트에서 prev는 상태 업데이트 함수에서 아주 중요한 개념이다. 이는 "이전 상태"를 의미한다.
< prev 의미 >
- prev는 상태 업데이트 함수에 전달되는 콜백의 매개변수로, 현재의 상태 업데이트가 적용되기 직전의 상태 값을 나타낸다. 이는 이전 상태 를 기반으로 새로운 상태를 계산할 때 사용함으로 안전한 업데이트를 할 수 있다. 또한, 리액트 상태 업데이트는 비동기적으로 일어날 수 있어, 항상 최신 상태를 보장하기 위해 사용한다.
< Spread Operator 사용 >
- spread operator (...todo)는 todo 객체의 모든 속성을 새로운 객체로 복사한다. 예를 들어 { id: todo.id, text: todo.text, completed: todo.completed }를 짧게 표현한 것이다. 이렇게 하면, 기존의 todo 객체를 그대로 복사하면서 특정 속성만 수정할 수 있다. 이 방식은 리액트의 상태 관리에서 중요한 불변성을 유지하는데 필수적이다.
# 과제를 하면서 알게된 점
1. 불리언 값, 즉 true나 false는 기본적으로 화면에 출력되지 않는다!
- 해결 방법: 불리언 값은 문자열이 아니기 때문에 출력되지 않아 화면에 아무것도 보이지 않는다 -> 불리언 값을 문자열로 바꾸어주면 된다!
- ex)
- {todo.completed.toString()} // -> toString()을 사용해줘서 불리언 값을 문자열로 바꿈!
2. JSX 문법 중괄호 '{}' 안에 들어가는 내용은 순수한 JavaScritp 표현식이어야 한다!
- 해결 방법: {${todo.text} ---- ${todo.completed.toString()} <button>완료</button>} JSX 표현식과 HTML 요소를 섞어 사용해 오류발생 -> HTML요소를 JSX 내에서 분리해 사용하면 됨!
- ex)
- <li key={todo.id}> {`${todo.text} ---- ${todo.completed.toString()}`} <button>완료</button> </li>
3. 버튼 클릭 핸들러에는 함수 참조를 전달해야 한다!
- 해결방법: <button onClick={handleUpdate(todo.id)}>완료</button> 부분에서 handleUpdate(todo.id)를 함수로써 바로 실행하고 있는 오류 -> 함수를 바로 실행하지 말고, 함수 참조를 전달하도록 수정하면 됨!
- ex)
- <button onClick={() => handleUpdate(todo.id)}>완료</button>
- 함수 호출: handleUpdate(todo.id) - 이렇게 작성하면 이 코드는 즉시 실행된다. 따라서 렌더링될 때마다 실행된다.
- 함수 참조: () => handleUpdate(todo.id) - 이 방식은 함수가 클릭될 때 실행되도록 미뤄둔 상태로 전달한다. 즉, 클릭할 때마다 handleUpdate(todo.id)가 실행된다.
'수준별 분반' 카테고리의 다른 글
리액트 베이직반 수업 1일차 (0) | 2024.08.12 |
---|---|
240801 걷기반 실습 (0) | 2024.08.01 |
240731 걷기반 수업 (0) | 2024.07.31 |
240730 걷기반 실습 (0) | 2024.07.30 |
240729 걷기반 수업 (0) | 2024.07.29 |