- useParams와 useLocation을 이용한 페이지 이동 (1)2022년 06월 05일
- 슬용이
- 작성자
- 2022.06.05.오후09:48
들어가기 전에
우리가 Web을 사용하다 보면 브라우저의 url이 페이지마다 바뀌는 것을 볼 수 있다.
리액트에서는 useParams와 useLocation 훅을 활용하여 구현할 수 있는데 이 두가지 훅들이 어떤 기능을 하는지 먼저 알아보자.
const params = useParams(); console.log(params);
useParams를 console로 확인해보면 객체Object로 id값이 들어있는 것을 볼 수 있다.
이 id값은 Rounter.js에 입력했던 path URL의 id 이다.
export default function Router() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Monsters />} /> <Route path="/monsters/detail/:id" element={<MonsterDetail />} /> </Routes> </BrowserRouter> ); }
그럼 useLocation을 console로 확인하면 어떤 값이 나올까?
const location = useLocation(); console.log(location);
다양한 값들이 나오는데 이 중에 우리가 주로 보아야할 부분은 pathname과 search 이다.
우리는 path parameter를 사용하고 싶을 땐 useParams를 쓸 수 있고,
query parameter를 사용하고 싶을 땐 useLocation을 통한 search 값을 쓸 수 있다.
이제 해당 id에 맞는 url을 불러와보자.
params는 id가 key인 객체이니 value값을 얻기 위해서 params.id를 입력하면 되는데,
url에서 인식이 되게 하기 위해서는 템플릿 리터럴을 사용해야 한다.
useEffect(() => { fetch(`https://jsonplaceholder.typicode.com/users/${params.id}`) .then((res) => res.json()) .then((data) => setMonster(data)); }, []);
그 후 console.log를 통해 해당 값을 잘 받아 오고 있는지 확인해보자.
console을 통해 data를 잘 가지고 오는 것은 확인을 하였다.
그러면 이제 해당 정보를 card에 넘겨주도록 하자.
const { id, name, email } = monster; // 구조분해 할당을 한 뒤
<Card id={id} name={name} email={email} /> // card 컴포넌트에 전달
그럼 detail에 정보값이 바뀐것을 확인할 수 있다
그런데 화면을 잘 살펴보면 잠깐 다른 화면이 떴다가 관련 정보가 나오는 것을 볼 수 있다.
이는 useEffect가 컴포넌트가 마운트 된 다음에 실행되는 동작 순서 때문에 생기는 일이다.
처음에는 useState({})의 초기값처럼 데이터가 비어 있는 상태인 것이다.
일단 return문을 통해 렌더가 된 후 useEffect의 fetch함수를 통해 setState로 값을 재설정해준다.
이걸 해결하기 위한 두 가지 방법이 있다.
- useEffect의 dependency array 활용
- 조건부 렌더링
dependency array는 useEffect내에 입력하는 부분으로, 해당 배열이 변경될 때만 작동하도록 한다.
다른 말로 표현하면 해당 배열이 변경만 되지 않는다면 보호될 수 있다는 뜻이다.
조건부 렌더링은 아래와 같이 적용할 수 있다.
{monster.name && ( <> <div className="btnWrapper"> <button>Back to Monsters List</button> </div> <Card id={id} name={name} email={email} /> <div className="btnWrapper"> <button>Previous</button> <button>Next</button> </div> </> )}
monster.name이 true일 때 뒷 부분을 렌더하는 조건이다.
단순히 monster && ~~ 으로 하지 않은 이유는 monster 값이 빈 객체 {} 여도 true로 받아들여 렌더가 되기 때문이다!
'React' 카테고리의 다른 글
query parameter를 사용하여 pagination 구현하기 (0) 2022.06.05 useParams와 useLocation을 이용한 페이지 이동 (2) (0) 2022.06.05 Comment component (0) 2022.05.30 import order convention (0) 2022.05.29 input과 type으로 알아보는 useState ⚛️ (0) 2022.05.21 다음글이전글이전 글이 없습니다.댓글