이전에 라우터를 통해서 경로에 따라 각기 다른 화면을 보여주는 방법에 대해서 배웠었습니다.
하지만 화면 하나를 구현하기 위해서 일일이 라우터의 패스를 지정해 주어야 한다면 무수히 많은 라우터가 생성되어야 합니다.
이 때 사용할 수 있는 것이 Path Parameter를 이용한 동적라우팅 입니다.
Path Parameter
localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125
라우트 경로 끝에 각기 다른 id 값들이 들어갑니다. 2, 45, 125.
url 경로에서 달라지는 부분을 저장하는 매개 변수를 Path Parameter 라고 합니다.
Path Parameter 는 Router 컴포넌트에서 다음과 같이 정의됩니다.
<BrowserRouter>
<Routes>
<Route path='/product/:id' element={<ProductDetail />} />
</Routes>
</BrowserRouter>
- : 는 Path Parameter 가 올 것임을 의미합니다.
- id 는 해당 Path Parameter 의 이름을 의미합니다. 변수 명을 짓듯이, 임의의 이름을 지정해줄 수 있습니다. ex) :productId
useNavigate : useNavigate을 통해 url을 변경시킵니다
useParams : useParams 를 통해 url안의 Id값을 받아옵니다
- 리스트 페이지의 개별 상품을 클릭 → navigate("/product/1") 로 상세 페이지로 이동합니다.
(X) onClick={
navigate(`./detail/${props.id}`);
}
(O) onClick={() => {
navigate(`./detail/${props.id}`);
}}
+ 컴포넌트에 navigate 온클릭 이벤트를 줄 때 애로우함수를 이용하여 콜백을 실행시켜야 했다.
+ navigate 경로 지정시 .을 안찍어서 페이지 경로 오류가 났었다. `/detail/${props.id}` --> './detail/${props.id}`
- 상세 페이지로 이동하면 url은 "http://localhost:3000/product/1" 과 같이 변경되어 있습니다.
- 페이지에 필요한 데이터를 useEffect 에서 fetching 합니다.
- 필요한 id는 URL에 존재하므로 useParams().id 에서 가져올 수 있습니다.
+ params.id 를 사용해야 하는데 params자체로 이용하려고 하여 에러가 났다.
- 해당 id를 가지고 백엔드에서 만들어준 API를 호출합니다.
function ProductDetail() {
const params = useParams();
useEffect(() => {
const productId = params.id;
fetch(`http://123.456.789:8000/products/${productId}`) // 1
.then(res => res.json())
.then(res => setData(res));
},[]);
return (
...
)
}
- 서버에서 가져온 데이터(res)를 컴포넌트의 data state 에 저장해 줍니다.
- state 에 담긴 데이터로 컴포넌트 UI 를 render 해줍니다.
Query Parameter
백엔드에서 가지고 있는 데이터는 많고, 그 데이터를 나눠서 보여줘야 할 때 사용됩니다. 일정 길이로 끊어서 데이터를 전달합니다.
ex) 총 40개의 상품이라면, 1페이지에 20개의 상품, 2페이지에 20개의 상품.
프론트엔드에서 현재의 위치(Offset)과 추가로 보여줄 컨텐츠의 수(Limit)를 백엔드에 전달합니다.
백엔드에서는 그에 해당하는 데이터를 끊어 보내주는 방식으로 구현하게 됩니다.
이 과정에서 Query Parameter(혹은, Query String, 쿼리 스트링)를 사용하게 됩니다.
쿼리 스트링이란 말 그대로 해당 엔드포인트에 대해 질의문(query)를 보내는 요청을 뜻합니다.
쿼리 파라미터는 페이지네이션, 필터 기능에 자주 쓰입니다.
예를 들어, localhost:8000/products?limit=10&offset=5 라는 주소가 있다고 가정해보겠습니다.
API 뒷 부분에 붙어있는 ? 로 시작하는 텍스트가 쿼리스트링 입니다.
?limit=10&offset=5 의 경우, "limit이 10이면서 offset이 5일 경우의 product 페이지를 보여달라" 는 요청으로 해석됩니다.
- ? 기호는 쿼리스트링의 시작을 알립니다. url 에서 ? 기호는 유일무이 합니다.
- limit : 한 페이지에 보여줄 데이터 수
- offset : 데이터가 시작하는 위치(index)
- parameter=value 로 필요한 파라미터의 값을 적습니다.
- 파라미터가 여러개일 경우 &를 붙여서 여러개의 파라미터를 넘길 수 있습니다.
Path Parameter 에 대한 정보가 useParams 훅이 반환한 객체 안에 담겨있었듯이,
쿼리스트링에 대한 정보는 useLocation 훅이 반환한 객체의 search 프로퍼티 안에 담겨있습니다.
useLocation
function ProductDetail(props) {
const location = useLocation();
console.log(location);
return (
...
)
}
useLocation 훅을 실행하면 경로 정보를 담고 있는 객체 를 반환합니다.
위 코드에서 해당 객체를 location 이라는 변수에 할당해 주었습니다. location 변수를 콘솔로 출력해 보면 아래의 로그가 출력 됩니다.
{
pathname: '/product/1',
search: '',
hash: '',
state: null,
key: 'default'
}
여러가지 정보가 있는데, 여기서 주목할 부분은 pathname 과 search 프로퍼티 입니다.
- pathname: 현재 경로 값
- search: 현재 경로의 query parameter 값
// current url -> localhost:3000/products?offset=10&limit=10
function ProductList() {
const location = useLocation();
console.log(location.search) // ?offset=10&limit=10
return (
...
)
}
이를 통해 url 에서 쿼리스트링 정보를 받아와서, 해당 정보를 통해 데이터를 요청할 수 있습니다.
fetch(`${API}${location.search}`)
.then(res => res.json())
.then(res => ...)
const LIMIT = 20;
export default function Users() {
const [users, setUsers] = useState([]);
const navigate = useNavigate();
const location = useLocation();
const updateOffset = (indexNumber) => {
const offset = indexNumber * LIMIT;
const queryString = `?limit=${LIMIT}&offset=${offset}`;
navigate(queryString);
};
// 데이터 로딩
useEffect(() => {
fetch(
`http://localhost:8000/users${
location.search || `?limit=${LIMIT}&offset=0`
}`
)
.then((res) => res.json())
.then((res) => setUsers(res.users));
}, [location.search]);
return (
<div className="photos">
<h1>Mini Project - Pagination</h1>
<Buttons updateOffset={updateOffset} />
<CardList users={users} />
</div>
);
}
동적 라우팅
- 리스트 페이지에서 카드를 클릭 합니다.
- url 이동을 합니다. 이때, 카드의 고유한 id 값이 url 에 포함됩니다.
- 이동한 페이지에서, url 에 담겨있는 id 값을 useParams 훅을 이용하여 가져옵니다.
- 가져온 id 값을 이용하여 데이터를 요청합니다.
페이지네이션
- 리스트 페이지에서 페이지 이동 버튼을 클릭 합니다.
- url 이동을 합니다. 이때 url 에는 각 버튼에 해당하는 쿼리스트링이 포함됩니다.
- 이동한 페이지에서, url 에 담겨있는 쿼리스트링을 useLocation 훅을 이용하여 가져옵니다.
- 가져온 쿼리스트링을 이용하여 데이터를 요청합니다.
'Frontend Study - 2 > React' 카테고리의 다른 글
React : React Datepicker 달력 라이브러리 캘린더 만들기 (0) | 2022.08.06 |
---|---|
React : useRef. 값이 변경되어도 렌더링 되지 않는 변수 만들기. (0) | 2022.07.24 |
React : Mock data 가져오기 / 조건부 렌더링 (0) | 2022.07.17 |
React : Ajax : Axios / fetch 의 차이 , 서버 통신 과정. (1) | 2022.07.13 |
React : Lifecycle & useEffect (0) | 2022.07.12 |