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

박정훈님의 프로필 이미지
박정훈

작성한 질문수

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

Uncaught TypeError: Cannot read properties of undefined (reading 'map') 에러

작성

·

5.2K

·

수정됨

2

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

export default function App () {


  const [todoData, setTodoData] = useState([
    {
      id:"1",
      title:"공부하기",
      completed: false,
    },
    {
      id:"2",
      title:"청소하기",
      completed: false,
    }
  ]);
  const [Value,setValue] = useState(""); // 첫번째 인수는 변수 두번재 인수는 state를 정하는 변수
  
  const btnStyle ={
    color: "#fff",
    border: "none",
    padding: "5px 9px",
    borderRadius: "50%",
    cursor: "pointer",
    float:"right",
  };
  
  const getStyle = (completed) => {
      return{
        padding:"10px",
        borderBottom:"1px #ccc dotted",
        textDecoration: completed ? 'line-through' : "none",
      };
  };

  const handleClick = (id) =>{
    let newTodoData = todoData.filter(data => data.id !== id)
    console.log("newTodoData",newTodoData)
    setTodoData(newTodoData);

  };

  const handleChange = (event) => {
      console.log("event",event.target.Value)
      setTodoData(event.target.Value);
  };

  const handleSubmit = (event) =>{  
    console.log("event",event)
    event.preventDefault(); // reload를 막아줌

    // 새로운 할일 데이터
    let newTodo ={  
      id: Date.now(),
      title : Value,
      completed: false,
    };
    
    // 원래 있던 할 일에 새로운 할일을 더해주기
    setTodoData(prev => [...prev,newTodo]);
    setValue("");
  };

  const handleCompleteChange = (id) => {
      console.log("todoData",todoData)
      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) => (
        <div style={getStyle(data.completed)} key={data.id}>
          <input type="checkbox" defaultChecked={false} onChange={() => handleCompleteChange(data.id)}/>
          {data.title}
          <button style={btnStyle} onClick={() => handleClick(data.id)}>x</button>
        </div>
        ))}

        <form style={{display:'flex'}} onSubmit={handleSubmit}>
          <input 
          type="text" 
          name="value" 
          style={{flex:'10', pedding:'50'}}
          placeholder="해야 할 일을 입력하세요."
          value={Value}
          onChange={handleChange}/>
          
          <input
          type="submit"
          value="입력"
          className="btn"
          style={{flex:'1'}}
          />
        </form>
      </div>
    </div>
    );
  
}

아래 코드에서 form에 어떠한 글자를 입력하면 Console 창에 왜 Uncaught TypeError: Cannot read properties of undefined (reading 'map')

에러가 발생하는지 도저히 모르겠습니다.

혹시 아시는분 답변 부탁드립니다.

감사합니다.

답변 1

2

John Ahn님의 프로필 이미지
John Ahn
지식공유자

안녕하세요

todoData?. map( 이런 식으로 물음표를 추가해서 해보시겠어요?

물음표에 뜻을 todoData && todoData.map

이것과 같습니다. todoData가 있을 때만 뒤에 로직을 수행한다는 것입니다.

아마 현재 todoData가 없는데 뒤에 저 부분을 렌더링 하려고 해서 그럽니다.

원래 1. 렌더링하고 2. useEffect가 실행되고 데이터를 가져오고 3. 가져온 데이터를 이용해서 다시 렌더링 합니다. 그러니 1번에서 현재 에러가 난 상태입니다.

감사합니다.

박정훈님의 프로필 이미지
박정훈

작성한 질문수

질문하기