#06 리액트 입문 :: todolist 오류 정리 | list should have a unique "key" prop. 외

728x90
반응형

1. 오류 : 배열 메소드 오류

 const initialState = [{ id: 0, title: '', body: '', isDone: false }];

▶ 실수한 부분: 배열 메소드인데 객체로 선언했었음..😢


2. 개선 : <input> 태그 이벤트 코드 수정

제목 <input value={title} onChange={(event) => titleHandler(event)}></input>

▶개선 사항 : event만 넘겨줄 경우, {titleHandler} 이렇게 변경해도 자동으로 event는 인자값으로 넘어감


3. 오류 : list should have a unique "key" prop.

return (
        <div>
            <div className="inputList">
                제목 <input value={title} onChange={titleHandler}></input>
                내용 <input value={content} onChange={contentHandler}></input>
                <button onClick={BtnAddClick}>추가하기</button>
            </div>
            <div className="app-style">
                {toDo.map(function (item) {
                    return (
                        <div key={item.id} className="toDoComponent-style">
                            <div>Working..</div>
                            <div>{item.title}</div>
                            <div>{item.content}</div>
                        </div>
                    );
                })}
            </div>
        <

▶  list should have a unique "key" prop.

-> map에서는 key값을 설정해줘야하는데 (상태값 변경시 식별에 도움) key값 설정을 잘못했음.

-> map에서 item으로 데이터를 가져오는데 toDo.id로 했음 -> item.id로 해줘야함.

 

▶배운 부분

화면이 실행되는 순간 todo.map()이 2번 출력됨 (= toDo.map 부분이 2번 실행됨)

-> onChange가 있어서 입력되는 만큼 실행되는 것이 맞음.  (id:0 으로 변함이 없음)


4. 개선 : id 값이 0 다음 2가 됨

 

const initialState = [{ id: 0, title: '', content: '', isDone: false }];
 
[버튼 클릭시] 
id: toDo.length + 1,
const initialState = [{ id: 1, title: '', content: '', isDone: false }];

 실수한 부분 : id 값은 배열의 초기값을 id = 0이 아닌 id=1로 줘야 원하는대로 출력됨

 


5. 오류 : 자식-부모 컴포넌트 구성 중에 오류 발생 

▶배운 부분

화살표 함수는 호이스팅이 되지 않음.. 그래서 함수 위치를 옮기거나, 화살표 함수를 안쓰거나 해야함. (그런것 같음)


6. 오류 : 상태값을 변경하는 버튼 (완료-취소) 동작 시, id가 동일 값 발생

 

    //[상태값] isDone : false > true 변경
    const BtnStateChangeClick = (clickedId) => {
        //선택된 id값을 filter찾아서 isDone : false > true 변경
        const ChangeToDone = toDo
            .filter((todoData) => todoData.id === clickedId)
            .map(function (item) {
                let newObj = [...toDo, (item.isDone = true)];
                return [...toDo, newObj];
            });

        //다시 한번 isDone= true인것만 filter로 추출
        const filteredDone = toDo.filter((todoData) => todoData.isDone === true);
        setTodo([...toDo, filteredDone]);
    };
setTodo([...toDo, filteredDone]);

 실수한 부분 : setTodo(filteredDone)이렇게 해서, 필터로 isDone이 true인 row 1줄만 출력

▶개선 사항 : 스프레드 용법을 사용하여 [기존 데이터 + 추가 배열] 추가했음.


7. 배운 부분 (중요 ★) 

* 데이터가 반영되었는지 확인하고싶을때 콘솔 위치 : state를 선언한 곳 아래 칸에

* 이유: 리랜더링이 끝나는 시점은 함수가 끝나고 함수가 재호출되는 시점!

* return 문을 지나서 함수가 끝나면, 함수는 죽고 재호출되는 시점에 신생아 같음

그러나 useState를 사용하는 state는 죽지 않음.

함수(사람) / useState( 도깨비 같이 수명이 길음 / 사용자가 reset하기 전까지는 죽지 않음)

function App() {
    const initialState = [{ id: 1, title: '', content: '', isDone: false }];
    const [toDo, setTodo] = useState(initialState);
    console.log(toDo);

그래서 여기 useState 아래에 콘솔을 찍어야 반영된 데이터를 확인 가능!

반응형