해결된 질문
작성
·
52
·
수정됨
0
그랩 선생님, 좋은 강의 만들어 주셔서 잘 듣고 있습니다.
그런데 아무리 해도 에러가 나는 것을 해결하지 못하고 있어 2주 이상 진도를 나가지 못하고 있어 부득이하게
질문을 여러번 올리게 됩니다.
현재 [그랩마켓] React로 웹 개발하기 -2 듣고 있는데요,
1.
그랩 선생님 소스 코드와 동일하게 아래 작성한 index.js 소스 첨부하는데요,
실행하면,
1초 동안 잠깐 판매되는 상품들 이미지 없이 전체 페이지 뜨다 바로 아래 첨부한 그림과 같이
에러가 발생 합니다.
이 에러는 어떻게 해결 할 수 있을까요?
--------
2. index.js 소스 아래에 작성 첨부 합니다.
import './index.css';
import axios from "axios";
import React from 'react';
function MainPage(){
const [products, setProducts]=React.useState([]);
React.useEffect(
function(){
axios.get("이곳에는 제 mock 목 서버 주소를 넣었습니다/products")
.then(function(result){
const products=result.data.products;
setProducts(products);
}).catch(function(error){
console.error("에러 발생:",error);
});
},[]); return (
<div>
<div id="header">
<div id="header-area">
<img src="../images/icons/logo.png" />
</div>
</div>
<div id="body">
<div id="banner">
<img src="../images/banners/banner1.png" />
</div>
<h1>판매되는 상품들</h1>
<div id="product-list">
{
products.map(function(product, index){
return (
<div className="product-card">
<div>
<img className="product-img" src={product.imageUrl} />
</div>
<div className="product-contents">
<span className="product-name">{product.name}
</span>
<span className="product-price">{product.price}원
</span>
<span className="product-seller">
<img className="product-avatar" src="../images/icons/avatar.png" />
<span>{product.seller}</span>
</span>
</div>
</div>
);
})
}
</div>
</div>
<div id="footer"></div>
</div>
);
}
export default MainPage;
그리고, 추가적으로 아래 그랩님 답변 본 뒤 다시 시도해 본 후 질문이 있어 추가적으로 글을 적습니다.
현재 postman을 실행하고요, 제 해당 목 mock 서버 주소를 입력 후 끝에 /products까지
하면요, 아래와 첨부한 사진과 같이 잘 데이터를 받아오는 것 같은데요, 위에 에러 화면이 그대로 표시되어 어떻게 해결해야 하는지 방법을 모르겠습니다. 조금 구체적으로 어떻게 해결해야 하는지 단계별로 친절한 설명 부탁드립니다
위에는 mock 서버인 postman(포스트맨) 화면이고요,
아래는 크롬 브라우저 에러 메시지를 첨부합니다.
참고> app.js 소스 첨부합니다.
import logo from './logo.svg';
import './App.css';
import MainPage from "./main/index.js"
function App() {
return (
<div>
<MainPage />
</div>
);
}
export default App;
또한 만약 그랩님께서 제 소스를 보시고 수정하여 에러가 해결된 완성된 index.js 소스가 있다면요,
최종 완성된 수십 줄의 소스 코드를 아래 답변 댓글에 길더라도 다 첨부해주시면 완성된 소스 코드를 그대로 복사하여 vs code에 붙여 넣기 하고 싶은데요, 아래 답변 글에 남겨주시면 감사하겠습니다.
-------------------------------------------------------------------------------------------------
그리고, 아래 글에 나와 있는 답변데로,
TypeError: Cannot read properties of undefined (reading ‘map’) 해결 방법
React 데이터 바인딩과 undefined 에러 처리
위 해결책의 코멘트와 답변 대로 수정해 보아도 에러가 해결 되지 않았습니다.
어떻게 해결 해야 하는지요? 빠른 답변 부탁 드립니다.
답변 2
1
상세하게 문제 사항 공유해주셔 감사합니다.
서버에서는 클라이언트(React 웹)에게 데이터를 전달해주고, 클라이언트는 이를 받아서 우리에게 시각화해서 보여주게 되는데요. 이때 서버 역할을 하는 Postman Mock Server에서는 products 정보를 약속된 규격인 JSON 포맷으로 전달해줘야 합니다. 그래야 클라이언트가 이를 해석할 수 있게 됩니다.
현재 올려주신 mock server의 응답값을 설정하는 이미지를 보면 빨간색으로 오류 선이 보이는 걸 알 수 있는데요. imageUrl의 값이 쌍따옴표("")가 아닌 따옴표('')로 되어있습니다. JSON 포맷으로 데이터를 주기 위해선 문자열은 모두 쌍따옴표로 감싸져야 합니다! 아래와 같이 응답값을 수정하시면 잘 동작할 것 같습니다.
{
"products": [
{
"name": "농구공",
"price": 10000,
"seller": "조던",
"imageUrl": "../images/products/basketball1.jpeg"
},
{
"name": "축구공",
"price": 50000,
"seller": "메시",
"imageUrl": "../images/products/soccerball1.jpg"
},
{
"name": "키보드",
"price": 10000,
"seller": "그랩",
"imageUrl": "../images/products/keyboard1.jpg"
}
]
}
추가적으로 성진님이 답변해주신 것 처럼 products의 값이 없을 때 경우를 대응해주면 product가 안보이지만 에러가 안나도록 설정은 할 수 있습니다!
나중에 서버를 직접 개발하게 되면서 코드가 또 변경될거라 우선 동작만 확인하고 넘어가주셔도 좋을 것 같습니다 :)
1
안녕하세요. 리액트 초기 렌더링 시 products의 값이 없어서 발생하는 문제인 거 같아요!
그래서 products의 값이 있을 경우에만 아래의 상품 컴포넌트들이 렌더링이 되도록 하는 게좋을 거 같아요.
products && products.length > 0 이 조건식을 사용하시면 작동될 거라고 봅니다!
제가 전체 소스코드가 없어서 테스트는 해보지 못했습니다!
<div id="product-list">
{products && products.length > 0 ? (
products.map((product, index) => (
<div className="product-card" key={index}>
<div>
<img className="product-img" src={product.imageUrl} />
</div>
<div className="product-contents">
<span className="product-name">{product.name}</span>
<span className="product-price">{product.price}원</span>
<span className="product-seller">
<img className="product-avatar" src="../images/icons/avatar.png" />
<span>{product.seller}</span>
</span>
</div>
</div>
))
) : (
<div>상품이 없습니다.</div>
)}
</div>
아 그리고 아래 데이터 패칭하는 부분 코드를 더 안전하게 처리하면 좋을거 같아요
result.data?.products || []
이렇게 옵셔널 체이닝을 사용하고 products가 없을 경우 다시 빈배열을 넣어주면 좋을거 같습니다.
React.useEffect(() => {
axios.get("서버주소/products")
.then((result) => {
setProducts(result.data?.products || []);
})
.catch((error) => {
console.error("에러 발생:", error);
});
}, []);
상세한 답변 주셔서 문제가 해결 되었습니다. 답변 진심으로 감사합니다.