React의 조건부 탐색

React 앱에서 프로그래밍 방식으로 새 페이지로 리디렉션하는 기능은 일반적인 작업입니다. 클라이언트 측 라우팅 라이브러리가 너무 많기 때문에 매우 쉬운 작업이기도 합니다.

오늘날의 React hooks 세계에서 일반적으로 필요한 것은 다음과 같습니다.

const history = useHistory() // react-router
const router = useRouter() // next.js
const nav = useNavigate() // reach-router (used in Gatsby)

history.replace('/path')
router.replace('/path')
nav('path', { replace: true })


그래서 문제가 무엇입니까?



탐색은 쉽지만 탐색은 매우 조건부인 경우가 많습니다.

예를 들어 사용자가 로그아웃했을 때 사용자가 일부 공개 페이지에 없는 경우에만 로그인 페이지로 보내려면 어떻게 해야 할까요? 지금은 비공개 페이지가 모두 경로/app 아래에 있고 다른 모든 페이지는 공개라고 가정해 보겠습니다.

레벨 1




useEffect(() => {
  const onPrivatePage = new RegEx(`\/app\/([0-9A-Za-z]+\/?)+/`).test(location.pathname)

  if(!isLoggedIn && onPrivatePage) {
    return goTo('/login')
  }

}, [isLoggedIn])


좋아, 논리는 따라하기가 매우 쉽지만 그 정규식은 약간의 버즈 킬입니다. 나는 그 똥을 구글링했다.

그러나 앱 대시보드에 로그인한 사용자가 /app 아래의 일부 페이지에 아직 없는 경우에도 리디렉션하려면 어떻게 해야 합니까? 위 코드에 추가할 수 있는 내용은 다음과 같습니다.

레벨 2




useEffect(() => {
  const onPrivatePage = new RegEx(`\/app\/([0-9A-Za-z]+\/?)+/`).test(location.pathname)

  if(!isLoggedIn && onPrivatePage) {
    return goTo('/login')
  }

  if(isLoggedIn && !onPrivatePage) {
    return goTo('/app/dashboard')
  }

}, [isLoggedIn])


흠... 좋아요 하나만 더 if 문은 아마도 아무도 죽이지 않을 것입니다.

하지만... 동적 경로가 있다면 어떻게 될까요? 예를 들어 /dashboard , /analytics , /profile , /messages 는 모두 개인용이며 하위 디렉토리도 마찬가지입니다.

다음과 같이 보일 수 있습니다.

레벨 3




useEffect(() => {
const onPrivatePage = new RegEx(`\/(profile|analytics|dashboard|messages)\/([0-9A-Za-z]+\/?)+/`).test(location.pathname)

  if(!isLoggedIn && onPrivatePage) {
    return goTo('/login')
  }

  if(isLoggedIn && !onPrivatePage) {
    return goTo('/app/dashboard')
  }

}, [isLoggedIn])


따라서 기본적으로 한 줄 패턴 일치를 수행하려면 정규 표현식을 수정해야 합니다. 나는 당신에 대해 모르지만 정규식은 눈에 쉽게 보이지 않습니다.

말로 표현하기에는 너무 단순한 것인데 코드에서는 표현력이 훨씬 떨어지는 것 같습니다.

더 나은 방법!



이것을 좀 더 우아한 방식으로 처리하기 위해 초소형 라이브러리를 만들었습니다. 소개...

React 사용 탐색



이 라이브러리의 유일한 목적은 조건부 탐색을 보다 표현적으로 만드는 것입니다. 어떤 반응 프레임워크나 클라이언트 측 라우팅 라이브러리를 사용하는지 상관하지 않습니다.

다음은 높은 수준의 기능입니다.
  • 작은. 단순한. 나타내는. 1.5kb gzip + 트리 쉐이킹.
  • TypeScript 준비됨
  • React 프레임워크에 구애받지 않음(Next.js, React Router, Reach Router 등)
  • 글로브 패턴 매칭 지원

  • React Use Navigate를 사용하는 것을 제외하고는 이전에 작성한 것과 동일한 코드를 사용하겠습니다.

    const { replace } = useNavigate()
    
    useEffect(() => {
      replace({
        goTo: '/login',
        when: !isLoggedIn,
        onPaths: ['/dashboard/**, 'analytics/**', '/profile/**', '/messages/**'],
        otherwiseGoTo: '/app/dashboard', 
      })
    
    }, [isLoggedIn])
    


    여기에서 무슨 일이 일어나고 있는지 알 수 있지만 한 줄씩 나누어 보겠습니다.
    goTo: '/login'조건부로 탐색하는 경로입니다.
    when: !isLoggedIn기본 부울 조건입니다.
    onPaths: ['/dashboard/**, 'analytics/**', '/profile/**', '/messages/**']탐색을 트리거하기 위해 사용자가 있어야 하는 경로입니다. 그것은 globs를 지원하므로 문제없이 하위 디렉토리를 일치시킬 수 있습니다.
    otherWiseGoTo: '/app/dashboard'when 또는 onPaths 조건이 모두 충족되지 않는 경우 탐색할 경로입니다.

    사용자가 특정 페이지에 없을 때 탐색하려면 어떻게 합니까?



    쉬운! onPathsnotOnPaths로 바꿀 수 있습니다.

    replace({
        goTo: '/app/dashboard',
        when: isLoggedIn,
        notOnPaths: ['/app/**'],
        otherwiseGoTo: '/login', 
      })
    


    경로 조건을 부정하는 것은 일반적으로 선호되지 않습니다. 알 수 있듯이 따르기가 약간 더 어려워지기 때문입니다. 우리는 다음과 같은 것을 쓸 수 있습니다:

    replace({
        goTo: '/login',
        when: !isLoggedIn,
        onPaths: ['/app/**'],
        otherwiseGoTo: '/app/dashboard', 
      })
    


    그러나 그것은 전적으로 당신에게 달려 있습니다!

    프레임워크에 구애받지 않는다고 했습니까?



    응 나는 했어. 나는 실제로 이전 예제에서 몇 가지 세부 사항을 남겼습니다. React Use Navigation은 실제로 탐색이 어떻게 작동하는지 신경 쓰지 않습니다.

    라이브러리는 클라이언트 측 라우팅 라이브러리에서 탐색 방법을 연결할 수 있는 NavigateProvider를 내보냅니다. 다음은 기본 Create React App 설정의 React Router입니다.

    import { NavigateProvider } from 'react-use-navigate'
    import { useHistory } from 'react-router-dom'
    
    const App = () => {
      const history = useHistory()
    
      const config = {
        push: history.push,
        back: history.back,
        replace: history.replace
      }
    
      return (
        <NavigateProvider {...config}>
          <RootComponent/>
        </NavigateProvider>
      )
    }
    


    이제 모든 중첩 구성 요소에서 useNavigate()를 호출할 수 있으며 구성에서 전달한 메서드를 사용합니다.

    그것은 거의 다룹니다. 부담없이 check out the docs . 의견에 대한 모든 피드백, 문제 또는 잠재적 사용 사례를 주시면 감사하겠습니다!

    좋은 웹페이지 즐겨찾기