programing

리액트 라우터 v6의 컴포넌트 외부 탐색

minimums 2023. 3. 29. 21:21
반응형

리액트 라우터 v6의 컴포넌트 외부 탐색

react-router v5에서 다음과 같은 이력 객체를 작성했습니다.

import { createBrowserHistory } from "history";
export const history = createBrowserHistory();

다음으로 라우터에 전달했습니다.

import { Router, Switch, Route, Link } from "react-router-dom";
<Router history={history}>
 ... my routes
</Router>

컴포넌트 이외에서 이력을 사용할 수 있도록 하기 위해 이 작업을 실시했습니다.

   // store action
    logout() {
        this.user = null;
        history.push('/');
    }

이렇게 해서 로직을 상점으로 옮겼더니 부품은 최대한 깨끗하게 유지되었습니다.그러나 리액트 라우터 v6에서는 같은 처리를 할 수 없습니다. '찾다'를 사용해서 할 수 있어요.useNavigate()에서는 수 .navigate제 가게에 쓰려고 했어요.른른른른 른른른?

RRDv6 라우터와 같은 방법으로 이력 상태를 인스턴스화하는 커스텀라우터를 실장하면 동작을 복제할 수 있습니다.

BrowserRouter 의 실장을 확인합니다.다음은 예를 제시하겠습니다.

export function BrowserRouter({
  basename,
  children,
  window
}: BrowserRouterProps) {
  let historyRef = React.useRef<BrowserHistory>();
  if (historyRef.current == null) {
    historyRef.current = createBrowserHistory({ window });
  }

  let history = historyRef.current;
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location
  });

  React.useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      basename={basename}
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
}

작성하다CustomRouterhistory"CHANGE: "CHANGE:

const CustomRouter = ({ history, ...props }) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      {...props}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
};

은 사실상 .historyRouter및 네비게이션 상태를 관리합니다.

서부터 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★CustomRouterhistory '오브젝트'의 Router에서 react-router-dom.

export default function App() {
  return (
    <CustomRouter history={history}>
      <div className="App">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/profile" element={<Profile />} />
        </Routes>
      </div>
    </CustomRouter>
  );
}

코드 및 상자 포크:

react-router-v6-컴포넌트 외부 탐색

갱신하다

react-router-dom@6는 이력 라우터를 표면화합니다.

이력 라우터

<unstable_HistoryRouter>라이브러리의 예를 소품으로 받아들입니다.이를 통해 해당 인스턴스를 비React 컨텍스트 또는 글로벌 변수로 사용할 수 있습니다.

import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
import { createBrowserHistory } from "history";

const history = createBrowserHistory({ window });

ReactDOM.render(
  <HistoryRouter history={history}>
    {/* The rest of your app goes here */}
  </HistoryRouter>,
  root
);

다음 주의사항이 있습니다.

는 현재 "API"로 가 붙습니다.unstable_ 두 될 수 .history.리액트 라우터가 내부적으로 사용하는 버전입니다. 추가하지 것이 history직접적인 의존관계로서 대신, 에서의 중첩된 의존관계에 의존합니다.react-router않는 되면 이 API를 삭제합니다.unstable_프레픽스

RRDv6.4+에 관한 주의사항

데이터 라우터를 사용하지 않고 RRDv6.4+를 사용하는 경우 좋은 소식은 다음과 같습니다.unstable_HistoryRouter는 아직 적어도 RRDv6.7.0을 통해 내보내고 있습니다.여기 레포에 기재된 이슈를 따라 하시면 됩니다.

하는 경우 된 ""을 사용하는 것입니다.navigate이치노

예:

import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter(...);

...

router.navigate(targetPath, options);

승인된 답변의 TypeScript 솔루션

이력 객체:

import { createBrowserHistory } from "history";

const customHistory = createBrowserHistory();

export default customHistory;

BrowserRouterProps는 리액트라우터 유형입니다.

export interface BrowserRouterProps {
  basename?: string;
  children?: React.ReactNode;
  window?: Window;
}

커스텀 라우터:

import { useLayoutEffect, useState } from "react";
import { BrowserRouterProps, Router } from "react-router-dom";
import { BrowserHistory } from "history";
import customHistory from "./history";
interface Props extends BrowserRouterProps {
  history: BrowserHistory;
}
export const CustomRouter = ({ basename, history, children }: Props) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location,
  });
  useLayoutEffect(() => history.listen(setState), [history]);
  return (
    <Router
      navigator={customHistory}
      location={state.location}
      navigationType={state.action}
      children={children}
      basename={basename}
    />
  );
};  

BrowserRouter 대신 CustomRouter 사용

ReactDOM.render(
  <React.StrictMode>
    <CustomRouter history={customHistory}>
      <App />
    </CustomRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

react-router-dom에서 HistoryRouter를 사용한 타이프스크립트 솔루션

다른 답변과 달리 이 솔루션에서는 리액트 라우터 도메인에서 가져온 HistoryRouter를 사용하며 TypeScript를 사용합니다.

1. CustomRouter 컴포넌트로 새 파일을 만듭니다.이 예에서는 ".components/CustomRouter.tsx"에 배치합니다.

import React, { FC, PropsWithChildren } from "react";
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
import { createBrowserHistory } from "history";

const history = createBrowserHistory({ window });

const CustomRouter: FC<PropsWithChildren> = ({ children, ...props }) => {
    return (
    <HistoryRouter history={history} {...props}>
        {children}
    </HistoryRouter>
    );
};

export const rootNavigate = (to: string) => {
    history.push(to);
};

export default CustomRouter;

2. CustomRouter를 Import하여 BrowserRouter 대신 사용합니다.

[...]
import CustomRouter from "./components/CustomRouter";
[...]
ReactDOM.render(
    <CustomRouter>
    [...]
    </CustomRouter>,
    root
);

3. "rootNavigate" anyware를 Import하여 사용합니다.

import { rootNavigate } from "../components/CustomRouter";

function doAnything() {
    alert("Ok, will do");
    rootNavigate("/anywhere-you-want");
}

리액트 라우터 돔 6.5

  1. createBrowserRouter를 사용하여 경로 설정

    import { createBrowserRouter } from "react-router-dom";
    
    const router = createBrowserRouter([
        {
          path: "/",
          element: <Root />,
          children: [
            {
              path: "children",
              element: <Children />,
            },
          ]
        }
     ])
    
  2. 라우터를 Import하고 라우터의 네비게이션 속성 메서드를 사용하여 지정된 경로로 리다이렉트합니다.

     import router from "@router/index";
    
     router.navigate("/auth/login");
    

HistoryRouter(React Router v6)를 사용한 다음 접근법이 효과가 있었습니다.

//1.
//create some file like HistoryRouterObject.ts, which will return the history
//object from anywhere
import { createBrowserHistory } from "history";

const historyObject = createBrowserHistory({ window });
export default historyObject;



//2.
//in your index.tsx, wrap your components with HistoryRouter and pass it the 
//historyObject above 
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
import historyObject from './somewhere in your app/HistoryRouterObject'

root.render(
<HistoryRouter history={historyObject}>
      //your components and Routers ...
</HistoryRouter>
);



//3.
//now  you can use the history object in any non-react component function, like IsUserAuthenticated.ts, 

import historyObject from './somewhere in your app/HistoryRouterObject'

function xyz(){
historyObject.replace('/');
//or
historyObject.push("/");
}

  1. 설치 내역:
yarn add history
  1. 작성하다history.ts(또는 js) 파일:
import { createBrowserHistory } from 'history';
export const history = createBrowserHistory();
  1. BrowserRouter를 불안정에서 HistoryRouter로 교체합니다.HistoryRouter, 이력을 인수로 사용합니다.
import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom';
import {history} from './history';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <HistoryRouter history={history}>
       ...
    </HistoryRouter>
  </React.StrictMode>
);
  1. 이제 React Components(ts 또는 js 파일) 외부로 이동할 수 있습니다.
import { history } from './history';
...
history.push('/');

React Router 6에는 다음 URL에서 사용할 수 있는 리다이렉트컴포넌트 메서드가 있습니다.https://reactrouter.com/en/main/fetch/redirect

언급URL : https://stackoverflow.com/questions/69871987/react-router-v6-navigate-outside-of-components

반응형