개발자
리액트로 투두리스트를 만들어보고 있는데 삭제 기능은 filter() 메서드로 구현하였고, 체크박스는 input에 css :checked로 구현하였습니다. 문제는 첫번째 항목을 체크하고 난 후에 리스트 앞부분에 새로운 항목을 추가해도 체크박스는 항상 첫번째 항목에 체크되어 있습니다... 인풋 박스를 독립적으로 빼서 컴포넌트로 사용하면 개별로 적용될거 같았는데 결과는 같았고, state로 체크 된 항목을 따로 관리해봤는데 그거또한 결과가 같았습니다...ㅠㅠ 리스트의 key는 map의 index로 사용하고 filter()로 삭제 기능을 구현하니 키는 마지막 순서만 삭제되면서 재렌더링으로 리스트가 변경되서 체크박스가 개별로 적용이 안되는것으로 예상이 됩니다만 너무 어렵네요ㅠ.. 구체적으로 도와주시면 감사하겠습니다ㅠㅠㅠ코드는 첨부했습니다!
1import { React, useCallback, useContext, useState } from 'react';
2import todoListFrame from"./TodoListFrame.module.css";
3import { ListSetContext } from '../context/ListSetContext';
4
5function TodoListFrame() {
6 const {todoList, setTodoList} = useContext(ListSetContext);
7
8 const onDelete = useCallback((index)=>{
9 setTodoList((prev)=>prev.filter((_,listId)=>listId !== index))
10 },[]);
11
12 return (
13 <div className={todoListFrame.listFrame}>
14 {todoList.map((content,index)=>{
15 return(
16 <li key={index} className={todoListFrame.listItem}>
17 <input type='checkbox' className={todoListFrame.checkBox}/>
18 {content}
19 <button className={todoListFrame.delBtn} onClick={()=> onDelete(index)}>❌</button>
20 </li>
21 )
22 })}
23 </div>
24 );
25}
26
27export default TodoListFrame;
커리어리 AI 봇
GPT가 달아주는 답변입니다.
2024년 05월 02일
코드를 보니, 체크 상태를 표현하는 state를 만들어 각 항목이 체크되었는지 관리하도록 수정해야 할 것 같습니다. 또한, map 함수에서 사용하는 key의 값을 고유하게 유지해야합니다. map의 index를 key로 사용하는 것은 권장되지 않습니다. 이는 단순히 배열의 순서만 의미하기 때문에, 배열에 변화가 생기면 원치 않은 결과를 초래할 수 있습니다. 다음은 각 항목에 대한 체크 상태를 관리하는 예제 코드입니다: ```javascript import { React, useCallback, useContext } from 'react'; import todoListFrame from "./TodoListFrame.module.css"; import { ListSetContext } from '../context/ListSetContext'; function TodoListFrame() { const {todoList, setTodoList} = useContext(ListSetContext); const onDelete = useCallback((id)=>{ setTodoList((prev)=>prev.filter((item)=>item.id !== id)) },[]); const onToggle = useCallback((id)=>{ setTodoList( todoList.map(item => item.id === id ? {...item, checked: !item.checked} : item, ), ); },[todoList]); return ( <div className={todoListFrame.listFrame}> {todoList.map(({id,content,checked})=>{ return( <li key={id} className={todoListFrame.listItem}> <input type='checkbox' checked={checked} onChange={() => onToggle(id)} className={todoListFrame.checkBox}/> {content} <button className={todoListFrame.delBtn} onClick={()=> onDelete(id)}>❌</button> </li> ) })} </div> ); } export default TodoListFrame; ``` 위의 코드에서는 todoList 각각의 아이템에 고유한 id와 checked라는 state가 추가되었습니다. 이제 체크박스는 항목별로 독립적으로 작동하게 됩니다. 또한, 삭제 기능은 고유한 id를 이용해 특정 항목을 삭제하도록 수정되었습니다. (tag기반으로 id를 생성하는 방법이나 다른 고유id 생성 라이브러리를 사용하면 좋습니다.)
지금 가입하면 모든 질문의 답변을 볼 수 있어요!