🎯v0.3 업데이트 내용
💡가게 정보 스타일 변경
✅ 기존 가게 정보 표시 방식을 보다 직관적이고 사용자 친화적으로 개선했습니다.
✅ 정보 수정 제안, 즐겨찾기, 거리뷰, 공유하기, 길 찾기 기능은 개발 예정이며 추후 업데이트를 통해 제공될 예정입니다.
✅ 소개 페이지를 추가했습니다.
<기존 팝업>
<업데이트된 팝업>
💡 반응형 CSS
✅ 반응형 디자인을 적용하여 모바일 기기에서도 최적의 사용자 경험을 제공하도록 개선되었습니다.
📒업데이트 공부하기
가게 정보를 담은 jsx를 따로 컴포넌트화 해서 관리하게 했다.
여기서 ReactDOM.createRoot를 사용했는데 ReactDOM.createRoot는 리액트 18에서 도입된 새로운 랜더링 API로, 이전 버전의 ReactDOM.render를 대체한다고 한다.
❗ ReactDOM.render / createRoot
리액트 17에서 사용되던 ReactDOM.render와 리액트18에서 새롭게 도입된 ReactDOM.createRoot 차이 알아보기
리액트 17의 ReactDOM.render는 동기 렌더링(Synchronous Rendering) 방식으로 작동된다고 한다.
동기 렌더링 방식은 렌더링 작업이 시작되면 React는 모든 컴포넌트와 DOM 업데이트를 완료하기 전까지 중단 없이 실행하는데
이러한 방식은 렌더링 작업이 길어질 경우 UI가 일시적으로 멈추거나 느려질 수 있다고 한다.
리액트 18의 ReactDOM.createRoot는 동시성 렌더링(Concurrent Rendering)을 지원하는데
createRoot를 사용하게 되면 React가 렌더링 작업을 여러 조각으로 나누어 처리할 수 있다고 한다.
여러 조각으로 나누어 처리하게 되면 렌더링 중에도 사용자 이벤트(버튼 클릭, 입력 상호작용 등등)를 우선 처리할 수 있다.
이를 통해 사용자 경험이 더 부드러워지고, 렌더링 중에도 UI가 응답성을 유지하게 된다.
API 차이도 있는데
ReactDOM.render는 단일 호출로 컴포넌트를 DOM에 직접 렌더링 하기 때문에 DOM 노드에 대한 제어권을 유지하지 않는다.
import ReactDOM from "react-dom";
ReactDOM.render(<App />, document.getElementById("root"));
ReactDOM.createRoot는 root 객체를 생성해서 DOM 컨테이너와 React 렌더링 작업 간의 연결을 관리한다.
root 객체는 render와 unmount 메서드를 통해 제어할 수 있다.
import ReactDOM from "react-dom/client";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
❗ 데이터 흐름 파악하기
지도가 있는 컴포넌트에서 axios를 통해 get("/fishstore") 요청을 보낸다.
이 과정들은 useEffect 내부에서 실행되고 성공적으로 데이터를 가져오면 response.data에 받아온 데이터가 저장된다.
그리고 가져온 데이터를 addStoreMarkers에 전달하게 된다.
useEffect(() => {
apiClient
.get("/fishstore")
.then((response) => {
const fishstores = response.data;
addStoreMarkers(fishstores, mapRef.current);
})
.catch((error) => {
console.error("가게 데이터를 가져오는 중 오류 발생:", error);
});
}, []);
addStoreMarkers는 fishstore 배열을 돌면서 각 가게들의 정보를 처리하고, 지도에 마커와 오버레이를 생성한다.
const addStoreMarkers = (fishstores, map) => {
fishstores.forEach((store) => {
const markerPosition = new window.kakao.maps.LatLng(store.storeX, store.storeY);
const overlayContent = document.createElement("div");
const root = ReactDOM.createRoot(overlayContent); // React 18 방식으로 root 생성
root.render(<StoreInfo store={store} />); // StoreInfo 컴포넌트에 store 데이터 전달
const customOverlay = new window.kakao.maps.CustomOverlay({
position: markerPosition,
content: overlayContent, // React로 렌더링된 DOM 요소를 오버레이로 사용
yAnchor: 1.2,
zIndex: 30,
});
window.kakao.maps.event.addListener(marker, "click", () => {
customOverlay.setMap(map);
});
});
};
addStoreMarkers에서 root.render(<StoreInfo store={store} />) 를 호출할 때,
StoreInfo 컴포넌트에 store 객체를 props로 전달한다. StoreInfo.jsx는 store 객체를 사용해 각 데이터들을 렌더링 한다.
추가적으로 정보 수정 제안, 즐겨찾기, 거리뷰, 공유하기, 길 찾기 기능을 제공할 예정이다.
const StoreInfo = ({ store, onClose }) => {
return (
<div className="storeinfo-container">
{/* 가게 정보 */}
<div className="storeinfo">
<div className="storeinfo-name">{store.storeName}</div>
<div className="storeinfo-rating">
<span>★★★★★</span>
<span className="review"></span>
</div>
<div className="storeinfo-address">{store.storeAddress || "정보 없음"}</div>
<a href="#" className="storeinfo-suggestion">정보 수정 제안</a>
<div className="storeinfo-actions">
<button className="storeinfo-button">즐겨찾기</button>
<button className="storeinfo-button">거리뷰</button>
<button className="storeinfo-button">공유</button>
<button className="storeinfo-button find-path">길찾기</button>
</div>
</div>
<button className="close-button" onClick={onClose}>
<img
src="https://img.icons8.com/?size=100&id=71200&format=png&color=000000"
alt="닫기 버튼"
className="close-button-icon"
/>
</button>
{/* 가게 이미지 */}
{store.storeImageBase64 && (
<div className="storeinfo-image-container">
<img
src={store.storeImageBase64}
alt={store.storeName}
className="storeinfo-image"
/>
</div>
)}
</div>
);
};
'Develop > React' 카테고리의 다른 글
붕어빵 프로젝트 업데이트 v1.0 (0) | 2024.12.26 |
---|---|
붕어빵 프로젝트 업데이트 v0.2 (0) | 2024.12.18 |
붕어빵 프로젝트 업데이트 v0.1 (1) | 2024.12.17 |
붕어빵 지도 프로젝트 도메인으로 배포하기 (2) (1) | 2024.12.15 |
붕어빵 지도 프론트 + 백엔드 (1) (3) | 2024.12.14 |