Each child in a list should have a unique key prop.
처음엔 todoList를 리스트렌더링할 때 idx값을 key값으로 넘겨줬었다.
근데 배열의 원소 순서가 바뀌면 index값도 바뀌고 컴포넌트마다 고유해야 하는 key값도 바뀌기 때문에 지양해야 한다고 한다.
그래서 나는 idx 부분을 todo.id로 바꿨고 저런 오류가 발생했다.
[초기 코드]
<ul>
{todoList.map((todo, idx) => (
<TodoItem
key={idx}
index={idx}
todo={todo}
todoList={todoList}
setTodoList={setTodoList}
/>
))}
</ul>
[수정 코드]
<ul>
{todoList.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
todoList={todoList}
setTodoList={setTodoList}
/>
))}
</ul>
코드를 수정했을때 id값을 찾지 못하는 것 같았다. 이거때문에 3일이라는 시간이 소요됨....
에러를 해결하는 방법을 엄청나게 찾아봤는데 해결방법이 2개가 있었다.
1. Key값을 정확하게 넣을 것
2. 감싸는 코드 (Fragment) <></>가 key보다 더 상위로 인식되었을 때
- 이 부분에서 key값이 Root 컴포넌트에 적용되어야 하는데 Fragment 부분이 Root로 map처리 되어서 발생하는 문제이다.
- 따라서 <></> 부분을 삭제하거나 <div>로 묶어준 후 div에 key값을 전달하면 된다.
그치만 나는 두 해결방안으로도 해결하지 못했다.
이유는 id값을 찾지 못해서였다. 하지만 나는 axios를 통해서 서버와 통신중이었고 create를 해주면 알아서 자동으로 id값이 생성된다.
도대체 왜!! 안나오는지!!!!!!! 3일동안 삽질하고 안되어서 내 주변에서 코딩을 제일 잘하는 사람에게 물어봤다.
함께 2시간넘게 같이 해결해줬는데 문제는 어디있었냐면.. 내가 todo를 받아오는 부분에 있었다.
나는 todo를 이렇게 "todo"라고 정직하게 받아오고 있었는데.. 이부분 때문에 이름이 겹쳐서 꼬인 것 같았다.
const [todo, setTodo] = useState("");
const [todoList, setTodoList] = useState([]);
서버와 통신할 때 todo라는 값을 넘겨주게 되는데.. 여기있는 todo와 내가 받는 todo.id의 todo가 겹쳐서 아마 문제가 발생한 것 같다..
const addTodo = async (e) => {
try {
await createTodo({
todo: todoInput,
});
await getTodo();
} catch (err) {
console.log(err);
}
};
이때 상태관리를 하는 todo를 todoInput으로 변경해줬고,
const [todoInput, setTodoInput] = useState("");
const [todoList, setTodoList] = useState([]);
todoInput을 서버 통신하는 쪽에 넘겨주니 todo.id가 잘 나오고 key값에 관한 에러도 해결이 되었다 😮
3일 넘게 삽질한 원인이 좀 허무맹랑하지만.. 이 맛에 개발하는거 같기도 하고 많이 배웠던 하루다.
리액트가 부족해서 그런지 더 공부해야겠다고 생각이 매일매일 드는 요즘이다.
만약 서버통신을 하고있고 나같은 원인이 발생한 사람이라면 이런 문제 해결방법은 나오지 않아서 글을 작성해봤다.
함께 해결해준 분에게 이 영광을 돌리며 리액트를 열심히 공부하자.. +서버통신하는 것도 +포스트맨 사용법도.. 🥲
'개발 > React' 카테고리의 다른 글
[React/AXIOS] localStorage를 이용해서 token 저장해 로그인 구현하기 (0) | 2023.06.12 |
---|---|
[React] select box value값 가져오기와 option 값이 나오지 않는 경우 (2) | 2023.03.26 |