react-module v6: 현재 루트의 경로 패턴 가져오기
현재 일치하는 경로의 경로 패턴을 얻을 수 있습니까?예를 들어:
<Route
path=":state/:city*"
element={
<Page />
}
/>
// Page.jsx
function Page() {
...
// usePathPattern doesn't actually exist
const pathPattern = usePathPattern(); // pathPattern = ":state/:city*"
...
}
도 쓸 수 거 알아useMatch현재 위치가 특정 경로 패턴과 일치하는지 여부를 확인하려면 구성 요소가 경로 패턴을 알아야 합니다.
을 맞춤 제작했습니다.useCurrentPath또, 이것은, 에게 있어서 기능합니다.
이 「」인 ./members/5566는 '경로'를 잡겠습니다./members/:id
import { matchRoutes, useLocation } from "react-router-dom"
const routes = [{ path: "/members/:id" }]
const useCurrentPath = () => {
const location = useLocation()
const [{ route }] = matchRoutes(routes, location)
return route.path
}
function MemberPage() {
const currentPath = useCurrentPath() // `/members/5566` -> `/members/:id`
return <></>
}
언급
https://reactrouter.com/en/v6.3.0/api#matchroutes
사용 사례를 완전히 해결할 수 있을지는 모르겠지만, 제 경우에는 다음 두 가지를 조합하여 사용했습니다.useLocation ★★★★★★★★★★★★★★★★★」useParams을 사용하다
import React from 'react';
import { useLocation, useParams } from 'react-router-dom';
import type { Location, Params } from 'react-router-dom';
/**
* Function converts path like /user/123 to /user/:id
*/
const getRoutePath = (location: Location, params: Params): string => {
const { pathname } = location;
if (!Object.keys(params).length) {
return pathname; // we don't need to replace anything
}
let path = pathname;
Object.entries(params).forEach(([paramName, paramValue]) => {
if (paramValue) {
path = path.replace(paramValue, `:${paramName}`);
}
});
return path;
};
export const Foo = (): JSX.Element => {
const location = useLocation();
const params = useParams();
const path = getRoutePath(location, params);
(...)
};
의 Routepath몇 가지 방법을 통해 정보를 얻을 수 있습니다.
는 조금 , 은 내가 제 the the the the the the the the the the my my my the the the the the the 했다는 것이다.path의 Route고객님께도 도움이 될 수 있는 다음과 같은 솔루션을 제공했습니다.
import {
matchPath,
useLocation
} from "react-router-dom";
const routes = [ ':state/:city', ...otherRoutes ];
function usePathPattern() {
const { pathname } = useLocation();
return matchPath( pathname, routes )?.path;
}
이것은 나에게 쉽게 통한다.
첫 번째로 반응성 도메인으로부터의 Import 사용 장소
import { useLocation } from "react-router-dom"
그리고나서
const location = useLocation();
console.log(location.pathname);
이것은 6.2.1 시점에서 실제로 내보내는 것과 동작하는 것처럼 보이지만, 안전하지 않게 내보내는 컴포넌트를 사용합니다.
import { UNSAFE_RouteContext } from 'react-router-dom';
const reconstructPath = (matches) =>
matches
.map(({ route: { path } }) =>
path.endsWith('/*') ? path.slice(0, -1) : path ? path + '/' : ''
)
.join('');
const findLastNode = (node) =>
node.outlet ? findLastNode(node.outlet.props.value) : node;
const usePathPattern = () =>
reconstructPath(
findLastNode(React.useContext(UNSAFE_RouteContext)).matches
);
지금은 OOB를 지원하지 않는 것 같아서 이 목적을 위해 커스텀훅을 작성했습니다.
주의: 아직 충분히 테스트되지 않았습니다.따라서 주의하여 사용하십시오.
import { useLocation, useParams } from 'react-router';
export function useRoutePathPattern() {
const routeParams = useParams();
const location = useLocation();
let routePathPattern = location.pathname;
Object.keys(routeParams)
.filter((paramKey) => paramKey !== '*')
.forEach((paramKey) => {
const paramValue = routeParams[paramKey];
const regexMiddle = new RegExp(`\/${paramValue}\/`, 'g');
const regexEnd = new RegExp(`\/${paramValue}$`, 'g');
routePathPattern = routePathPattern.replaceAll(
regexMiddle,
`/:${paramKey}/`,
);
routePathPattern = routePathPattern.replaceAll(regexEnd, `/:${paramKey}`);
});
return routePathPattern;
}
react-router v6를 해야 .matchPath배열과 .모든 루트는 배열과 같은 변수에 저장해야 합니다.다음으로 모든 루트를 루프하고 그 기능을 사용하여 일치하는 루트를 찾을 수 있습니다.이 값은 첫 번째 truthy 값과 일치하므로 렌더링한 순서와 같은 순서로 루프를 반복해야 합니다.
같은 변수에 네스트된 루트를 저장하지 않으면 네스트된 루트를 처리할 수 없기 때문에 이 솔루션은 완벽한 솔루션이 아닙니다.
다음은 예를 제시하겠습니다.
routes.ts를 참조해 주세요.
const routes = [
{ name: 'Home', path: '/home', element: Home },
{ name: 'Profile', path: '/profile', element: Profile },
{ name: '404', path: '*', element: NotFound },
];
App.tsx
<App>
<BrowserRouter>
<Header />
<Routes>
{routes.map((route, key) => (
<Route key={key} path={route.path} element={<route.element />} />
))}
</Routes>
</BrowserRouter>
</App
useMatchedRoute.tsx
import { matchPath } from 'react-router';
export function useMatchedRoute() {
const { pathname } = useLocation();
for (const route of routes) {
if (matchPath({ path: route.path }, pathname)) {
return route;
}
}
}
Header.tsx
export function Header() {
const route = useMatchedRoute();
return <div>{route.name}</div>
}
나는 Blazor와 c#에서 왔기 때문에 꽤 다르다.그래도 내 방식대로 할 것 같은데...
여기에서는 최신 버전의 리액트 라우터 돔(V6.3.0)을 사용하고 있습니다.
기본적으로 어레이 내의 모든 개인 루트 이름을 선언한 후 어레이에서 사용자가 의도한 경로를 검증합니다.
또한 라우터가 리다이렉트처를 알 수 있도록 isLogged 파라미터를 전달하고 있습니다.
로그인 컴포넌트에서 나중에 사용자가 원하는 위치를 알 수 있으며 로그인 후 사용자가 원하는 위치로 리다이렉트할 수 있습니다(이 예에서는 구현되지 않은 기능).
import {useRoutes, useNavigate, useLocation} from "react-router-dom";
export const RouteHandler = ({isLogged} : any) : any => {
let location = useLocation();
let navigate = useNavigate();
let privateRoutes : string[] = [
"/dashboard",
"/products"
//add more private stuff here
];
if(privateRoutes.includes(location.pathname))
{
if(!isLogged)
{
navigate(`/login?return=${location.pathname}`);
}
}
else
{
//will go to not found
}
return useRoutes([
{
path: "/login",
element: <h2>Login component</h2>
},
{
path: "/dashboard",
element: <h2>You are now logged in</h2>
},
{
path: "*",
element: <h2>Page not found</h2>
},
]);
}
사용법은 다음과 같습니다.
import {RouteHandler } from './mylocation';
<RouteHandler isLogged={true}/>
나는 그것이 미래에 몇몇 사람들에게 도움이 되기를 바란다.
리액트 라우터 v6의 경우:
import { matchPath, useLocation } from "react-router-dom";
const routes = ["/", "/login", "product", "product/:id"];
const usePathPattern = (): string | undefined => {
const { pathname } = useLocation();
return routes.find((route) => matchPath(route, pathname));
};
@RichN 님의 답변에 감사드립니다.나는 그의 답변을 개선/수정하고 리액트 라우터와 호환되도록 노력했다.
import { UNSAFE_RouteContext } from 'react-router-dom'
function usePathPattern () {
let lastRouteContext = useContext(UNSAFE_RouteContext)
while (lastRouteContext.outlet) lastRouteContext = lastRouteContext.outlet.props.routeContext
return lastRouteContext.matches
.map(({ route: { path } }) => path).filter(Boolean)
.join('/').replaceAll(/\/\*?\//g, '/')
}
샘플 출력:
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/*
또는 다음 중 하나를 선택합니다.
return lastRouteContext.matches.reduce((patternPath, { route: { path } }) =>
patternPath + (path
? path.endsWith('*') ? path.slice(0, -1) : path.endsWith('/') ? path : path + '/'
: ''
), '')
샘플 출력:
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/
그렇지만.....
... (저와 마찬가지로) 풀 패턴이 아닌 여기(사용처)까지 일치한 패턴을 알아야 하는 경우 마지막 패턴을 찾기 위해 루트 컨텍스트로 이동할 필요가 없습니다( )findLastNode@RichN's answer).
이것으로 충분합니다.
const useLocationPattern = () => useContext(UNSAFE_RouteContext).matches.reduce((patternPath, { route: { path } }) =>
patternPath + (path
? path.endsWith('*') ? path.slice(0, -1) : path.endsWith('/') ? path : path + '/'
: ''
), '')
샘플 출력:
# In a near-to-root component:
/:localeCode/:orgName/
# In a very nested component (for the same URL):
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/
지금은 할 수 없습니다.다음으로 회피책을 제시하겠습니다.
<Route path="/:state" element={<LocationView />} />
<Route path="/:state/:city*" element={<LocationView city />} />
같은 컴포넌트를 여러 경로로 렌더링하려고 하는 것 같습니다.경로 패턴을 체크하는 대신 컴포넌트에 부울 프로펠러를 추가할 수 있습니다(이 경우).city) 및 프로펠러가 사실인지 확인합니다.
import { useMatch, Route, Routes } from "react-router-dom";
<Routes>
<Route path="/" element={<Element1 match={useMatch("/")} />} >
<Route path=":id" element={<Element2 match={useMatch("/:id")} />} />
</Route>
</Routes>
질문에 대한 직접적인 답변은 아니지만, 이 질문을 얻으려고 노력하다가 이 질문을 발견한params에서match오브젝트, 이제 이 작업을 수행할 수 있습니다.useParams갈고리를 채우다
import { Route, Routes } from 'react-router-dom';
import { useParams } from 'react-router';
<Routes>
<Route path="/:id" element={<MyComponent />} />
</Routes>
...
function MyComponent() {
const { id } = useParams();
return <div>{id}</div>
}
유용했으면 좋겠다.
언급URL : https://stackoverflow.com/questions/66265608/react-router-v6-get-path-pattern-for-current-route
'programing' 카테고리의 다른 글
| Java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinition예외. (0) | 2023.03.21 |
|---|---|
| angular.js의 커스텀필터 의존관계로서 서비스를 주입하는 방법 (0) | 2023.03.16 |
| URL의 매개 변수로 JSON 배열을 전달하는 방법 (0) | 2023.03.16 |
| bash에서 CSV를 JSON으로 변환 (0) | 2023.03.16 |
| angularJS - 마우스 클릭으로 x 및 y 위치 가져오기(div) (0) | 2023.03.16 |