리액트에서 용도에 맞게 페이지 이동시키기

Daisy🌼·2022년 11월 22일
1
post-custom-banner

🤔 리액트에서 화면 이동을 처리하기 위해서는 Link 컴포넌트를 사용하거나 useNavigate라는 hook을 사용한다. 둘 다 화면 이동과 관련된 기능인데, 각각의 방법을 어떤 경우에 사용하는 것이 적절할지 고민하게 되었다.

Link란?

  • react-router-dom에 의해 <a> 태그로 렌더링 되는 컴포넌트

  • 특정 요소를 클릭하면 바로 이동하도록 하는 데 용이

  • 상품을 클릭하면 상품 상세 페이지로 이동하는 기능

  • map() 메서드를 사용해 각각의 상품 컴포넌트를 Link 컴포넌트로 감싸줄 수 있습니다.

  • 저는 Link 컴포넌트와 map() 메서드를 조합해 팀프로젝트에서 다음과 같이 사용했습니다.

// 피드(feed) 정보들이 담긴 feed 배열
// Link 컴포넌트로 감싸주었다.
{feed &&
	feed.map(item => {
		return (
			<S.FeedItem key={item.feedId}>
				<Link to={`/${FEED_PATH}/${item.feedId}`}>
					<Image src={item.image} />
				</Link>
			</S.FeedItem>
		)
})}

📌 useNavigate

useNavigate란?

  • 특정 경로로 이동시켜주는 함수를 리턴하는 hook

  • 특정 조건을 만족하면 이동하도록 하는 데 용이

useNavigate 활용

  • 사용자의 로그인 유무에 따라 로그인 페이지로 이동시키는 기능

  • 예를 들어 로그인한 사용자만 이용할 수 있는 기능을 유저가 요청했을 때, 로그인 되어 있는지를 먼저 확인하여 만약 로그인되어있지 않다면 로그인 페이지로 이동시키는 기능을 만들 수 있습니다.

  • 저는 팀프로젝트에 적용할 때 좋아요 버튼을 클릭하면 실행되는 함수 handleLikeClick을 정의해, 해당 함수에서 로그인 여부를 체크하는 조건문을 추가했습니다.

  • 해당 팀프로젝트에서 redux-toolkit을 사용했기 때문에 로그인 여부를 나타내는 stateisLogin 을 가져와 로그인 여부를 확인했고, 로그인하지 않았을 경우 로그인 페이지로 이동시키고 early return 시켰습니다.

// 로그인 여부를 나타내는 state를 store에서 가져온다.
const { isLogin } = useAppSelector(state => state.user)

const handleLikeClick = (feedId: number, isLike: boolean) => {
	if (!isLogin) {
		alert('로그인이 필요한 서비스입니다🐱')
		// 로그인 페이지로 이동시키고 handleLikeClick 함수를 종료한다.
		return navigate('/login')
	}

/*로그인되어 있을 경우 처리하는 로직 생략*/

}

🤔 reat-router 공식 문서를 참고하다가, Link 컴포넌트 뿐만 아니라 이름이 비슷한 NavLink라는 컴포넌트도 있었다. 얼핏 봤을 때는 Link와 비슷하게 페이지를 이동시키는 역할을 하지만 차이점이 존재하는 것 같아서 추가해보기로 했다!

  • react-router 공식 문서에서 설명하는 navLink 컴포넌트는 아래와 같습니다.

NavLinkactive 상태의 여부를 아는 특별한 종류의 Link입니다. NavLink는 브레드크럼 또는 탭같은 탐색 메뉴를 만들 때 유용합니다. 또한 스크린리더와 같은 보조 기술에 유용한 컨텍스트를 제공합니다.

  • NavLink 는 active 상태를 가질 수 있는 Link 컴포넌트입니다. 실제로 NavLink 컴포넌트는 내부적으로 isActive 값에 따라 클래스네임이나 스타일링을 커스터마이징 할 수 있도록 구현되어 있습니다.
declare function NavLink(
  props: NavLinkProps
): React.ReactElement;

interface NavLinkProps
  extends Omit<
    LinkProps,
    "className" | "style" | "children"
  > {
  caseSensitive?: boolean;
  children?:
    | React.ReactNode
  	//isActive 값에 따라 자식 요소를 커스터마이징할 수 있다.
    | ((props: { isActive: boolean }) => React.ReactNode);
  className?:
    | string
    //isActive 값에 따라 클래스네임을 커스터마이징할 수 있다.
    | ((props: {
        isActive: boolean;
      }) => string | undefined);
  end?: boolean;
  style?:
    | React.CSSProperties
    //isActive 값에 따라 스타일을 커스터마이징할 수 있다.
    | ((props: {
        isActive: boolean;
      }) => React.CSSProperties);
}

NavLink 컴포넌트와 styled-components를 활용한 브레드크럼(Breadcrumbs) 컴포넌트 예제를 소개하는 좋은 글이 있어 링크를 첨부합니다.

원문 Smarter, Dumb Breadcrumb
번역 컴파운드 컴포넌트 잘만들기 2편 : Smarter, Dumb Breadcrumb

특히 해당 원문은 컴파운트 컴포넌트 패턴을 활용해 브레드크럼을 만든 것으로 보이는데요, 아래 포스팅을 번역하고 컴파운트 컴포넌트 패턴에 대해 설명하는 글을 추가적으로 첨부합니다.

리액트 디자인패턴 : Compound Components (컴파운드 컴포넌트 패턴)

정리

  • Link는 주로 요소를 클릭했을 때 다른 페이지로 이동시켜주는 데 사용

  • useNavigate는 주로 특정 조건에 따라 다른 페이지로 이동시켜주는 데 사용

  • NavLinkisActive라는 prop에 따라 컴포넌트를 커스터마이징 하는 데 사용


참고자료

Link v6.4.3

useNavigate v6.4.3

NavLink v6.4.3

[React] Link & useNavigate

profile
커피와 재즈를 좋아하는 코린이 | 좋은 글 좋은 코드를 쓰고 싶습니다
post-custom-banner

0개의 댓글