재렌더링이 안됨

이윤희·2025년 1월 2일

React/Next 일기

목록 보기
8/52

배경

쇼핑몰 구현중에...
컴포넌트를 만들어서 map으로 화면에 뿌리기까지 했다! 일단 오류 없이 잘 나왔는데...

//App.js

import data from "./data.js";

function App() {

   let [shoes] = useState(data);
  
      <div class="container ">
        <div className="row">

          {shoes.map((a, i) => {
            return (
              <Product index={i} shoes={shoes} />
            );
          })}
        </div>
      </div>
    </div>
  );
}

function Product(props) {
  return (
    <div class="col-md-4">
      <img src={props.shoes[props.index].img} width="80%" />
      <h4>{props.shoes[props.index].title}</h4>
      <p>{props.shoes[props.index].price}</p>
    </div>
  );
}

export default App;

여기서 데이터를 더 늘려보고 싶어서 data.js의 데이터들을 여러개 복사해서 넣어 봤다.
근데 데이터를 3개에서 6개로 늘렸으니 당연히 6개가 출력되어야 하는데, 그대로 3개만 출력이 됨

왜 안 될까?


let data = [
  {
    id: 0,
    title: "White and Black",
    content: "Born in France",
    price: 120000,
    img: "https://codingapple1.github.io/shop/shoes1.jpg",
  },

  {
    id: 1,
    title: "Red Knit",
    content: "Born in Seoul",
    price: 110000,
    img: "https://codingapple1.github.io/shop/shoes2.jpg",
  },

  {
    id: 2,
    title: "Grey Yordan",
    content: "Born in the States",
    price: 130000,
    img: "https://codingapple1.github.io/shop/shoes3.jpg",
  },
  
  // 여기부터 추가함
  {
    id: 3,
    title: "White and Black",
    content: "Born in France",
    price: 120000,
    img: "https://codingapple1.github.io/shop/shoes1.jpg",
  },

  {
    id: 4,
    title: "Red Knit",
    content: "Born in Seoul",
    price: 110000,
    img: "https://codingapple1.github.io/shop/shoes2.jpg",
  },

  {
    id: 5,
    title: "Grey Yordan",
    content: "Born in the States",
    price: 130000,
    img: "https://codingapple1.github.io/shop/shoes3.jpg",
  },
];

export default data;

알고 보니 재렌더링이 안돼서 HTML을 다시 안불러온거였다!!!

let [shoes, setShoes] = useState(data);

이렇게 해주니 자동으로 업데이트 됨!


GPT

주어진 코드에서 data.js의 데이터를 추가했음에도 출력되는 결과가 늘어나지 않는 이유는 React 컴포넌트 상태(state)가 한 번 설정된 이후, 해당 상태를 업데이트하지 않으면 변경 사항이 반영되지 않기 때문입니다.

문제의 원인

  1. App.js에서 useState를 사용하여 데이터를 상태로 설정했습니다:

    let [shoes] = useState(data);

    useState는 컴포넌트가 처음 렌더링될 때 한 번만 실행됩니다. 따라서, data.js를 수정하더라도 React는 shoes 상태를 업데이트하지 않으므로 렌더링 결과가 바뀌지 않습니다.

  2. data.js의 변경 사항은 프로젝트가 다시 컴파일될 때 적용됩니다. 그러나 shoes 상태는 이미 초기값으로 설정된 상태라 업데이트되지 않습니다.


해결 방법

data.js의 변경 사항이 React 상태에 반영되도록 하려면, useState의 초기값을 동적으로 가져오도록 코드를 수정해야 합니다.

방법 1: import를 상태 초기값에 직접 사용

useState의 초기값으로 data를 직접 불러오면 컴파일 시 최신 데이터가 반영됩니다:

let [shoes, setShoes] = useState(data);

이 경우, data.js를 변경한 후 프로젝트를 다시 실행하면 데이터가 업데이트됩니다.


방법 2: useEffect를 사용해 데이터 동기화

useEffect를 사용해 data.js가 변경될 때 React 상태를 업데이트하도록 설정할 수 있습니다:

import { useEffect } from "react";
import data from "./data.js";

function App() {
  let [shoes, setShoes] = useState([]);

  useEffect(() => {
    setShoes(data); // 최신 데이터를 상태에 반영
  }, []); // 빈 배열을 넣으면 컴포넌트가 마운트될 때 한 번 실행

  return (
    <div className="App">
      <Navbar bg="dark" data-bs-theme="dark" className="nav">
        <Container>
          <Navbar.Brand href="#home">C Shop</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#features">Features</Nav.Link>
            <Nav.Link href="#pricing">Pricing</Nav.Link>
          </Nav>
        </Container>
      </Navbar>

      <div className="main-bg"></div>
      <div className="container">
        <div className="row">
          {shoes.map((a, i) => (
            <Product key={i} index={i} shoes={shoes} />
          ))}
        </div>
      </div>
    </div>
  );
}

function Product(props) {
  return (
    <div className="col-md-4">
      <img src={props.shoes[props.index].img} width="80%" />
      <h4>{props.shoes[props.index].title}</h4>
      <p>{props.shoes[props.index].price}</p>
    </div>
  );
}

export default App;

방법 3: 상태를 업데이트하는 버튼 추가

UI에 버튼을 추가하여 데이터를 수동으로 업데이트할 수도 있습니다:

function App() {
  let [shoes, setShoes] = useState(data);

  const updateShoes = () => {
    setShoes(data); // data.js를 다시 불러와 상태 업데이트
  };

  return (
    <div className="App">
      <button onClick={updateShoes}>Update Shoes</button>
      <div className="container">
        <div className="row">
          {shoes.map((a, i) => (
            <Product key={i} index={i} shoes={shoes} />
          ))}
        </div>
      </div>
    </div>
  );
}

0개의 댓글