1. 문제 상황
서로 다른 두 페이지에서 같은 버튼을 사용해야하는 상황이였다.
wishList 부분에서 메이트 신청 버튼 부분과 restaurantList 부분에서 메이트 신청 버튼 부분에서 같은 폼으로 각 페이지에서 고른 Place의 정보를 넘겨주는 상황에서 문제 발생
2. 어떤 문제인가..🫨
처음에는 위시리스트에서 메이트 신청 버튼 사용 상황을 생각하지 못하고, 맛집리스트에서 localStorage 를 이용해 place의 정보를 저장했었다.
const newPlaceData = {
placeId: placeData.id,
placeName: placeData.place_name,
placeAddress: placeData.address_name,
placeRoadAddress: placeData.road_address_name,
placePhone: placeData.phone,
placeUrl: placeData.place_url,
placeLat: placeData.y,
placeLng: placeData.x,
};
localStorage.setItem('placeInfo', JSON.stringify(newPlaceData));
window.location.href = `/eatMate/mateForm?category=${category}`;
같은 방식으로 위시부분에서도 localStorage에 set 할까 했지만 메이트 폼에서 위시에서 온 place 정보인지 맛집에서 온 place 정보인지 구별해서 처리하는 것보다 각자 부분에서 선택한 place 정보를 보내주는 편이 유지보수 측면에서 나을듯하여 구글링과 챗지피티 검색 후 useNavigate 와 useLocation 을 이용해 데이터를 처리하기로 결정! 🔫
let navigate = useNavigate();
const handleClickMate = () => {
// navigate 함수를 사용하여 place 데이터와 함께 mateModal 경로로 이동
navigate('/mateModal', { state: { place: place } });
};
return ( <button onClick={handleClickMate}>메이트 찾기</button> );
import { useLocation } from 'react-router-dom';
function MateModal() {
const location = useLocation();
const { place } = location.state || {}; // state가 없는 경우를 대비한 기본값 설정
console.log(place); // 여기에서 place 객체에 접근할 수 있습니다.
// place 객체를 사용한 렌더링 또는 로직 구현...
return (
<div>
{/* place 데이터를 활용한 UI 구성 */}
</div>
);
}
챗지피티가 알려준 방식대로 코드를 짰는데...
useNavigate 를 사용해 데이터를 전송하면 계속해서
Cannot read properties of undefined (reading 'placeName')
TypeError: Cannot read properties of undefined (reading 'placeName')
at MateModal (http://localhost:3000/main.a700f1324c57a9f24fe0.hot-update.js:221:31)
ERROR
"undefined" is not valid JSON
SyntaxError: "undefined" is not valid JSON
at JSON.parse (<anonymous>)
at MateModal (http://localhost:3000/main.5b1a571147ea2585727f.hot-update.js:78:26)
at renderWithHooks (http://localhost:3000/static/js/bundle.js:96408:22)
at updateFunctionComponent (http://localhost:3000/static/js/bundle.js:99288:24)
at beginWork (http://localhost:3000/static/js/bundle.js:101000:20)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:86004:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:86048:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:86105:35)
at beginWork$1 (http://localhost:3000/static/js/bundle.js:105969:11)
at performUnitOfWork (http://localhost:3000/static/js/bundle.js:105217:16)
이동한 페이지에서 해당 객체를 찾으면 계속 undefined 관한 오류가 떴다..
3. 문제 해결 ing ⛏️..⛏️...
계속 객체의 형태를 바꾸고 이름을 바꾸고 별 난리를 쳤는데
알고보니 const { place } = location.state;
{} 중괄호를 감싸고 받아서 안 받아지는거였다..;;
리액트(React)에서 중괄호 {}를 사용하여 변수를 감싸는 것은 JSX 내에서 JavaScript 표현식을 사용하고자 할 때 필요합니다. JSX는 HTML과 비슷한 문법을 사용하지만, 실제로는 JavaScript를 확장한 것이기 때문에, JavaScript 표현식을 사용하려면 중괄호를 사용해야 합니다.
챗지피티만 맹신했다가 계속 삽질을 하고 있었던 것 .. 😑
useNavigate
useNavigate Hook 은 네비게이션 함수를 반환한다. 이 함수를 사용하여 애플리케이션 내에서 다른 경로로 이동하거나, 현재 경로를 대체하거나, 이전 페이지로 돌아가는 등의 네비게이션 작업을 수행할 수 있다.
부모에서 자식, 자식에서 부모로 값을 전달하는 상황은 보통 props로 해결이 된다.
그러나 페이지를 이동하면서 값을 전달해야하는 상황은 부모와 자식의 관계가 아니기 때문에 다른 방법으로 해결해야한다.
바로 기존 페이지에서 useNavigate()*로 값을 전달하고, 새로운 페이지에서 useLocation()으로 값을 받아오는 방법이다.
* React-dom-router v6 기준
useLocation
useLocation Hook은 현재 페이지의 URL 정보를 담고 있는 객체를 반환한다. 이 객체는 pathname, search, hash, state 등 여러 속성을 포함하고 있으며, useNavigate를 통해 전달된 state는 useLocation 를 통해 사용할 수 있다.
useNavigate 사용법
먼저, react-router-dom 패키지를 설치해야 한다.
npm install react-router-dom --save
useNavigate 는 state 옵션을 사용해서 네비게이션 대상 페이지에 상태(state)를 보낼 수 있다.
state 키의 값으로는 전달하고자 하는 상태(객체, 문자열, 숫자 등 어떤 자바스크립트 데이터도 가능)를 지정한 뒤 네비게이션 대상 페이지에서는 useLocation 훅을 사용하여 이 상태를 받아올 수 있다.
예시를 통해 useNavigation 과 useLocation 의 사용법을 알아보자 🔦
import React from 'react';
import { useNavigate } from 'react-router-dom';
function LoginPage() {
const navigate = useNavigate();
function handleLoginSuccess() {
navigate('/dashboard', { state: { from: 'login' } });
}
return (
<div>
{/* 로그인 로직 */}
<button onClick={handleLoginSuccess}>Login</button>
</div>
);
}
navigate 함수를 통해 path (이동하는 페이지 경로 값) 와 전달할 데이터 값을 설정해준다.
from 이라는 key 값으로 'login' 이라는 문자열을 담아줬다.
import React from 'react';
import { useLocation } from 'react-router-dom';
function Dashboard() {
const location = useLocation();
const fromLogin = location.state?.from === 'login';
return (
<div>
{fromLogin && <p>Welcome back! You just logged in.</p>}
{/* 대시보드 컨텐츠 */}
</div>
);
}
이동한 페이지에서 useLocation 함수를 이용해 state에서 key 값을 통해 값을 얻어올 수 있다.
let navigate = useNavigate();
const handleClickMate = (place) => {
// 필요한 place 데이터를 mateModal 경로로 전달
navigate(`/eatMate/mateForm?category=${category}`, { state: {place: place}});
};
const location = useLocation();
console.log(typeof location.state);
console.log(location.state);
const placeInfo = location.state.place
이렇게 바꿨더니 잘 받아졌다 ㅎㅎ!
앞으론 맹신하지말고 구글링 잘 하고 정확히 잘 알아봐야겠다.. 🥺
'트러블슈팅' 카테고리의 다른 글
[mac] ora-01033: oracle initialization or shutdown in progress (0) | 2024.05.08 |
---|---|
[#0] 트러블슈팅 (0) | 2024.04.09 |