Dynamic Segments

양은지·2023년 4월 26일
0

React

목록 보기
24/27

Dynamic Segments

URL segment들은 파싱된 후 다양한 API에 제공되는 동적 placeholder로 사용될 수 있다.
다시 말하면 path="dashboard" 처럼 정해진 정적 url segment가 아닌 path:=":name"를 사용하게 되면 :name segment 자리에 입력된 값으로 유동적 url로 부여할 수 있고, 이 값을 API에 제공할 수 있게 된다.

Path, params

아래와 같이 Route path가 지정되어 있을 때,

<Route path="projects/:projectId/tasks/:taskId" />

:projectId, :taskId 두 세그먼트들은 유동적인 url input 값을 받게 되고, 현재 위치가 "projects/abc/tasks/3"일 때 입력된 abc, 3의 값은 loader, action에 제공될 수 있다.

//If the current location is /project/abc/tasks/3
<Route 
  path="projects/:projectId/tasks/:taskId"
  // sent to loaders
  loader={({ params }) => {
  	params.projectId; // abc
    params.taskId; // 3
  }}
  // and actions
  action={({ params }) => {
  	params.projectId; // abc
    params.taskId; // 3
  }}
  element={<Task />}
/>;

useParams()

Route에서 전달한 params를 해당 컴포넌트에서 사용할 때는 useParams() hook을 사용할 수 있다.
useParams hook은 해당 path와 매칭되는 dynamic segments params의 obj key/value를 반환하며, params에는 부모 개체의 projectId, taskId 정보를 모두 자식 개체에 상속하며 params' chain으로 사용할 수 있다.

import { useParams } from "react-router-dom";

function Task() {
  // returned from `useParams`
  const params = useParams();
  params.projectId; // abc
  params.taskId; // 3
}

useMatch()

useMatch() hook은 url 정보를 parameter로 넘길 때, parameter 값과 현재의 url 정보가 일치하는 지를 판단해주는 기능을 한다.
일치할 경우 url 정보를, 일치하지 않을 경우 null을 반환하기 때문에 주로 현재 접속해 있는 url을 탭 UI에 반영시킬 때 쓸 수 있다. (접속 중인 url tab에 active style 적용)

function Random() {
  const match = useMatch(
  	"/projects/:projectId/tasks/:taskId"
  );
  match.params.projectId; // abc
  match.params.taskId; // 3
}

Combined dynamic segments

dynamic segments는 부분적으로만 적용하여 사용할 수는 없다.

  • "/teams-:teamId" (x)
  • "/teams/:teamId" (o)
  • "/:category--:productId" (x)
  • "/:productSlug" (o)

만약 "/:category--:productId" 등과 같이 결합된 dynamic segments를 사용해야만 하는 상황이라면 다음과 같이 직접 url을 파싱하는 과정을 넣어줘야 한다.

function Product() {
  const { productSlug } = useParams();
  const [category, product] = productSlug.split("--");
  // ...
}

Optional Segments

부가적으로 붙게 되는 url segment에 대해서는 segment 뒤에 ?를 불여 optional segment로 정의해 줄 수 있다. (static segment에도 적용 가능, /project/task?/:taskId)

<Route 
  // this path will match URLs like
  // - /categories
  // - /en/categories
  // - /ko/categories
  path="/:lang?/categories"
  // the matching params might be available to the loader
  loader={({ params }) => {
    console.log(params["lang"]); // "en"
  }}
  // and the action
  actions={({ params }) => {}}
  element={<Categories />}
/>;

Splats

"catchall"이나 "star" segment로도 알려진 /* segment를 사용하면 / 뒤에 붙는 모든 url에 대해 segment로 매칭할 수 있다.

<Route 
  // this path will match URLs like
  // - /files
  // - /files/one
  // - /files/one/two
  // - /files/one/two/three
  path="/files/*"
  // the matching param will be avaiable to the loader
  loader={({ params }) => {
  	console.log(params["*"]); // "one/two"
  }}
  // and the action
  action={({ params }) => {}}
  element={<Team />}
/>;

function Team() {
  let params = useParams();
  console.log(params["*"]); // "one/two"
}

splats segments를 새로운 변수에 넣어 사용하기 위해서는 다음과 같이 destructuring하여 파싱해주면 된다. (보통 새로운 변수 이름은 splat으로 사용한다)

let { org, "*": splat } = params;

Ranked Route Matching

입력한 URL을 Route와 매치할 때, 아래처럼 우선 순위가 겹칠 수 있는 경우가 있다. 이 때 React Router는 더 명확하게 매칭되는 경우로 라우팅해준다.

<Route path="teams/:teamId" />
<Route path="team/new" />

https://example.com/teams/new 라는 URL로 접속했다고 가정해보면, new는 :teamId로 될 수 있겠지만 /new 라는 더 명확하게 매칭되는 Route를 피킹한다.

Reference

react router - dynamic segments

profile
eunji yang

0개의 댓글