쇼핑몰 구현중에...
컴포넌트를 만들어서 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);
이렇게 해주니 자동으로 업데이트 됨!
주어진 코드에서 data.js의 데이터를 추가했음에도 출력되는 결과가 늘어나지 않는 이유는 React 컴포넌트 상태(state)가 한 번 설정된 이후, 해당 상태를 업데이트하지 않으면 변경 사항이 반영되지 않기 때문입니다.
App.js에서 useState를 사용하여 데이터를 상태로 설정했습니다:
let [shoes] = useState(data);
useState는 컴포넌트가 처음 렌더링될 때 한 번만 실행됩니다. 따라서, data.js를 수정하더라도 React는 shoes 상태를 업데이트하지 않으므로 렌더링 결과가 바뀌지 않습니다.
data.js의 변경 사항은 프로젝트가 다시 컴파일될 때 적용됩니다. 그러나 shoes 상태는 이미 초기값으로 설정된 상태라 업데이트되지 않습니다.
data.js의 변경 사항이 React 상태에 반영되도록 하려면, useState의 초기값을 동적으로 가져오도록 코드를 수정해야 합니다.
import를 상태 초기값에 직접 사용useState의 초기값으로 data를 직접 불러오면 컴파일 시 최신 데이터가 반영됩니다:
let [shoes, setShoes] = useState(data);
이 경우, data.js를 변경한 후 프로젝트를 다시 실행하면 데이터가 업데이트됩니다.
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;
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>
);
}