인프런 커뮤니티 질문&답변

choi님의 프로필 이미지

작성한 질문수

따라하며 배우는 리액트 A-Z[19버전 반영]

클래스 컴포넌트 -> 함수형 컴포넌트 바꾸기 에러 ㅠㅠ

22.09.13 17:12 작성

·

294

1

안녕하세요 현재 <To-Do 앱을 클래스 컴포넌트에서 함수형 컴포넌트로 바꾸기> 까지

진도를 따라가고 있는 수강생입니다.

클래스 컴포넌트-> 함수형으로 변경하고 있는데

아래 에러가 계속 뜨고 있습니다.ㅠㅠ 원인을 모르겠어서 맨 하단에 코드를 전부 복사해놓았습니다.

확인해봐주시면 감사하겠습니다 : )

 

import React, { useState } from "react";
import "./App.css";

// 함수형 component로 작업한 todoList
export default function App() {

  const btnStyle = {
    color: "#fff",
    border: "none",
    padding: "5px 9px",
    borderRadius: "50%",
    cursor: "pointer",
    float: "right",
  }
  const getStyle = (completed) => {
    return {
      padding: "10px",
      borderBottom: "1px dotted #ccc",
      textDecoration: completed ? "line-through" : "none"
    }
  };
  
  const {todoData, setTodoData} = useState([]);
  const {value, setValue} = useState("");

  // 할일 삭제
  const handleDelete = (id) => {
    let newTodoData = todoData.filter((data) => data.id !== id);
    setTodoData(newTodoData);
  };

  // 할일 input text에 입력
  const handleChange = (e) => {
    setValue(e.target.value)
  };

  // 입력된 value 목록에 추가
  const handleSubmit = (e) => {
    e.preventDefault();
    let newTodo = {
      id: Date.now(),
      title: value,
      completed: false,
    };
    // 원래 있던 할 일에 새로운 할 일 더해주기
    setTodoData((prev) => [...prev, newTodo]);
    setValue("");
  };

  // 완료된 내용 체크하여 상태 변경 해주기
  const handleCompleteChange = (id) => {
    let newTodoData = todoData.map((data) => {
      if (data.id === id) {
        data.completed = !data.completed;
      }
      return data;
    });
    setTodoData(newTodoData);
  }

  return (
    <div className="container">
      <div className="todoBlock">
        <div className="title">
          <h1>할일 목록</h1>
        </div>
        { todoData.map((data,index)=> (
          <div style={getStyle(data.completed)} key={data.id}>
            <input 
              type="checkbox" 
              id={data.id}
              onChange={() => handleCompleteChange(data.id)}
              defaultChecked={false}/>
            <label htmlFor={data.id}>{data.title}</label>
            <button 
              style={btnStyle} 
              onClick={() => handleDelete(data.id)}>
              x
              </button>
          </div>
        ))}
        
        <form style={{display:'flex', marginTop: '20px'}} onSubmit={ handleSubmit }>
          <input 
            type="text" 
            name="value" 
            style={{ flex:'10', padding:'5px'}} 
            placeholder="해야할 일을 입력하세요." 
            value={ value } 
            onChange={ handleChange }/>
          <input 
            type="submit" 
            value="입력" 
            className="btn" 
            style={{ flex:1 }}/>
        </form>
      </div>
    </div>
  )
}

답변 1

0

팡tae님의 프로필 이미지

2022. 09. 14. 14:40

안녕하세요 아직 함수형컴포넌트로 바꾸기 강의는 아직 듣진 않았지만 검색 결과 && 연산자를 사용해서 코드를 작성하시면 에러없이 출력되는 걸 확인했습니다.

이유는 map함수는 처음 데이터가 들어오지 않아도 랜더링이 시작되어 undifined이 정의 되어있어서 위와 같은 오류가 발생한다고 나와있네요. 자세한건 에러내용을 복사해서 구글링 하시면 원하시는 답을 찾으실 수 있을 것 같습니다.
{ todoData&&todoData.map((data,index)=> (~~~
이런식으로 작성해주시면 될것같아요.
자세한건 저도 선생님 댓글을 봐야할 것 같습니다. 도움이 안되서 죄송해요

 

choi님의 프로필 이미지
choi
질문자

2022. 09. 14. 15:21

네 맞아요. 콘솔을 찍으면 계속 undifined로 나오더라구요 ㅠ

태진님 말대로 해보니 오류없이 잘 작동하네요~ 정말 정말 감사합니다!

관련 자료는 저도 좀 더 찾아봐야겠습니다.

강의 영상에서 수업 하셨던 코드로는 && 연산자 없이 잘 출력되고 있어서 쌤 답변도 넘 궁금하네용 ㅠ

 

+ &&연산자를 사용해서 해결했다고 생각했는데, 그 다음엔 또 "setValue is not a function" 이라는 에러도 팡팡 터지고 있어요 ...ㄷㄷ

팡tae님의 프로필 이미지

2022. 09. 14. 23:10

혹시 에러 내용과 코드를 한번 보여주실수 있을까요? 주제넘지만 저도 공부하면서 공유하고싶어서요!
저는 올려주신 코드에서 && 사용해서 변경하니까 코드는 정상작동 됐어요! 추가적으로 코드 기입하시면서 바뀐게 있다면 공유 부탁드리겠습니다!!

choi님의 프로필 이미지
choi
질문자

2022. 09. 15. 09:54

코드는 바뀐거 없이 말씀해주셨던대로 &&연산자만 추가했어요~

{ todoData&&todoData.map((data,index)=> (
          <div style={getStyle(data.completed)} key={data.id}>
            <input 
              type="checkbox" 
              id={data.id}
              onChange={() => handleCompleteChange(data.id)}
              defaultChecked={false}/>
            <label htmlFor={data.id}>{data.title}</label>
            <button 
              style={btnStyle} 
              onClick={() => handleDelete(data.id)}>
              x
              </button>
          </div>
        ))}

setValue is not a function, setTodoData is not a function

줄줄이 에러가 터지는데... 중간에 제가 뭘 안했나 싶기도하고 ㅠㅠ 수업 7번은 돌려봤는데도 모르겠네요..

팡tae님의 프로필 이미지

2022. 09. 16. 17:07

아 코드 다시보니까 !! useState사용시에 const [] 대괄호를 써줘야하는데 중괄호 오타났어요!!
이미 해결하셨을것 같지만! 그래도 댓글달아봅니다 ㅎㅎ

 const {todoData, setTodoData} = useState([]);
  const {value, setValue} = useState("");

이부분을

 const [todoData, setTodoData] = useState([]);
  const [value, setValue] = useState("");

이렇게 바꾸시면돼요!

팡tae님의 프로필 이미지

2022. 09. 16. 17:17

const [] 이렇게 바꿔주시면 map쪽도 todoData.map((data,index)=>(
~~~~
) )
써도 동작을 하네요 . map쪽 에러 복사해서 구글링해서 &&연산자가 나왔나봅니다!!

choi님의 프로필 이미지

작성한 질문수

질문하기