반응 라우터 V4를 사용하여 프로그래밍 방식으로 탐색


336

방금 react-routerv3에서 v4 로 교체 했습니다.
그러나의 멤버 함수에서 프로그래밍 방식으로 탐색하는 방법을 잘 모르겠습니다 Component. 즉 handleClick()기능 에서 /path/some/where일부 데이터를 처리 한 후 탐색하고 싶습니다 . 나는 다음과 같이 그것을 사용했다.

import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')

그러나 v4에서 이러한 인터페이스를 찾을 수 없습니다.
v4를 사용하여 탐색하려면 어떻게해야합니까?


3
props를 통해 v4의 히스토리 오브젝트에 액세스 할 수 있습니다. this.props.history.push ( '/')
colemerrick

6
다른 장소에서 액세스하려면 어떻게해야 Component합니까? 예를 들어, redux 조치 내부.
Maximus S

73
때로는 왜 하나의 링크에서 다른 링크로 이동하는 것이 그렇게 복잡한 지 궁금합니다. =))
Thai Tran

12
오늘날에는 시대의 방향 전환이 그렇게 복잡하지 않을 것이라고 생각할 것입니다.
JohnAllen

:이 게시물 도움이되었다고 medium.com/@anneeb/redirecting-in-react-4de5e517354a
BioData41

답변:


414

브라우저 환경을 대상으로하는 경우 react-router-dom대신 패키지 를 사용해야 합니다 react-router. 이들은 두 개의 개별 패키지를 설치할 필요가 없다는 미묘한 차이로 코어 ( react)와 플랫폼 별 코드 ( react-dom, react-native) 를 분리하기 위해 React와 동일한 접근 방식을 따르고 있으므로 환경 패키지에 모든 것이 포함됩니다. 당신은 필요합니다. 다음과 같이 프로젝트에 추가 할 수 있습니다.

yarn add react-router-dom

또는

npm i react-router-dom

가장 먼저해야 할 일은 <BrowserRouter>응용 프로그램에서 가장 상위 상위 구성 요소로 제공하는 것입니다. <BrowserRouter>HTML5 historyAPI를 사용하고 관리하므로 직접 인스턴스화하여 <BrowserRouter>구성 요소에 소품으로 전달할 필요가 없습니다 (이전 버전에서와 같이).

V4에서는 프로 그래 매틱 방식으로 탐색하려면 애플리케이션에서 최상위 컴포넌트로 제공자 컴포넌트 가있는 한 historyReact를 통해 사용 가능한 오브젝트 에 액세스 해야합니다. 라이브러리는 컨텍스트를 통해 개체 자체를 속성으로 포함 합니다. 인터페이스는 다음과 같은 여러 가지 탐색 방법을 제공합니다 , 그리고 다른 사람의 사이에서. 여기 에서 전체 속성 및 메서드 목록을 확인할 수 있습니다 .context<BrowserRouter> routerhistoryhistorypushreplacegoBack

Redux / Mobx 사용자에게 중요한 참고 사항

애플리케이션에서 redux 또는 mobx를 상태 관리 라이브러리로 사용하는 경우 위치를 인식해야하지만 URL 업데이트를 트리거 한 후 다시 렌더링되지 않는 구성 요소 관련 문제가 발생할 수 있습니다.

컨텍스트 모델을 사용하여 구성 요소로 react-router전달 location하기 때문에 발생 합니다.

connect와 observer는 shouldComponentUpdate 메소드가 현재 props와 다음 props를 얕게 비교하는 컴포넌트를 만듭니다. 해당 구성 요소는 하나 이상의 소품이 변경된 경우에만 다시 렌더링됩니다. 즉, 위치가 변경 될 때 업데이트되도록하려면 위치가 변경 될 때 변경되는 소품이 제공되어야합니다.

이를 해결하기위한 두 가지 접근 방식은 다음과 같습니다.

  • 당신의 랩 연결된 길이없는에서 구성 요소를 <Route />. 현재 location객체는 <Route>렌더링하는 구성 요소에 전달 하는 소품 중 하나입니다.
  • 연결된 컴포넌트를 withRouter고차 컴포넌트로 감싸십시오 . 실제로는 location소품 과 동일한 효과가 있고 주입 됩니다.

이를 제외하고 권장 사항에 따라 순서대로 프로그래밍 방식으로 탐색하는 네 가지 방법이 있습니다.

1.- <Route>컴포넌트 사용

선언적 스타일을 촉진합니다. v4 이전에는 <Route />구성 요소가 구성 요소 계층의 맨 위에 배치 되었으므로 미리 경로 구조를 고려해야했습니다. 그러나 이제 트리의 어느 위치 에나<Route> 구성 요소 를 배치 할 수 있으므로 URL에 따라 조건부 렌더링을보다 세밀하게 제어 할 수 있습니다. 를 분사 , 및 구성 요소에 소품으로. 탐색 방법 (예를 들면 , , ...)의 특성으로서 사용할 수있는 개체.RoutematchlocationhistorypushreplacegoBackhistory

, 또는 props Route를 사용 하여을 사용하여 무언가를 렌더링하는 방법에는 3 가지가 있지만, 같은 것을 여러 개 사용하지 마십시오 . 선택은 유스 케이스에 따라 다르지만 기본적으로 처음 두 옵션은 URL 위치와 일치하는 경우에만 컴포넌트를 렌더링 하는 반면 , 컴포넌트 와 함께 경로가 위치와 일치하는지 여부는 렌더링됩니다 (URL을 기반으로 UI를 조정하는 데 유용함) 어울리는).componentrenderchildrenRoutepathchildren

컴포넌트 렌더링 출력을 사용자 정의render 하려면 match, location및을 제외한 원하는 다른 소품을 컴포넌트에 전달하려면 컴포넌트를 함수로 감싸고 옵션을 사용해야합니다 history. 설명하는 예 :

import { BrowserRouter as Router } from 'react-router-dom'

const ButtonToNavigate = ({ title, history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    {title}
  </button>
);

const SomeComponent = () => (
  <Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)    

const App = () => (
  <Router>
    <SomeComponent /> // Notice how in v4 we can have any other component interleaved
    <AnotherComponent />
  </Router>
);

withRouterHoC 사용

이 고차 컴포넌트는와 같은 소품을 주입합니다 Route. 그러나 파일 당 하나의 HoC 만 가질 수 있다는 제한이 따릅니다.

import { withRouter } from 'react-router-dom'

const ButtonToNavigate = ({ history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    Navigate
  </button>
);


ButtonToNavigate.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
  }),
};

export default withRouter(ButtonToNavigate);

Redirect구성 요소 사용

를 렌더링하면 <Redirect>새 위치로 이동합니다. 그러나 기본적으로 현재 위치는 서버 측 리디렉션 (HTTP 3xx)과 같은 새로운 위치로 대체됩니다. 새 위치는 toprop 에 의해 제공되며 문자열 (리디렉션 할 URL) 또는 location객체 일 수 있습니다. 새 항목을 히스토리푸시하려면push 소품도 전달 하고로 설정하십시오.true

<Redirect to="/your-new-location" push />

router컨텍스트를 통해 수동으로 액세스

컨텍스트 는 여전히 실험적인 API이므로 React의 향후 릴리스에서 중단 / 변경 될 가능성이 있기 때문에 약간 실망 했습니다.

const ButtonToNavigate = (props, context) => (
  <button
    type="button"
    onClick={() => context.router.history.push('/my-new-location')}
  >
    Navigate to a new location
  </button>
);

ButtonToNavigate.contextTypes = {
  router: React.PropTypes.shape({
    history: React.PropTypes.object.isRequired,
  }),
};

말할 것도없이 메모리에<NativeRouter> 탐색 스택을 복제하고 패키지를 통해 사용 가능한 React Native 플랫폼을 대상 으로 하는 것과 같은 비 브라우저 에코 시스템을위한 다른 라우터 구성 요소도 있습니다 .react-router-native

자세한 내용은 공식 문서를 참조하십시오 . 라이브러리의 공동 저자 중 한 명이 반응 라우터 v4에 대한 멋진 소개를 제공 하는 비디오 가 있으며 주요 변경 사항 중 일부를 강조 표시합니다.


2
V4를 사용하고 있으며 위의 작업은 정상적으로 작동합니다. 이상한 선택이있는 것 같지만 위의 동작은 확실히 작동하기 때문에 V4 라우터를 다루는 데 상당한 시간을 보냈습니다. 나는 당신이 수입 withRouter하고 있다고 가정합니다react-router-dom
Sam Parmenter

3
withRouter에서 가져 오는 중 입니다 react-router-dom. history.push는 URL을 변경하지만 <Route>페이지를 강제로 새로 고침 할 때까지는 로드되지 않는 것 같습니다 .
BreakDS

1
@rauliyohmc 나는 이것에 대해 틀렸다. 문제는 내가 <Router> 꾸미고있는 React 컴포넌트 안에이 문제@observer 를 유발한다는 것이다. 해결 방법은 이러한 모든 React 구성 요소에 대한 것입니다. @withRouter
BreakDS

3
이 위대한 대답을 withRouter겪는 사람들에게는 단순히 Route후드 를 사용하는 HOC입니다 . 즉 , 소품, 기록, 경기 및 위치 3 개만 사용합니다 . 위의 예에서는에 추가 할 push소품 인 것으로 보이지만 사실은 아닙니다. 대신 사용해야합니다. 이것이 약간 혼란 스러웠던 다른 사람들을 돕기를 바랍니다. withRouterButtonToNavigateprops.history.push
vinnymac

39
와. browserHistory.push('/path/some/where')훨씬 간단 해 보입니다. 저자는 명령형 프로그래밍을 권장하지 않지만 때로는 더 잘 작동합니다!
lux

149

가장 쉬운 방법은 다음과 같습니다.

this.props.history.push("/new/url")

노트 :

  • history prop사용 불가능한 경우 상위 컴포넌트에서 조치를 호출하려는 컴포넌트로 전달할 수 있습니다.

10
4.0 라우터를 사용하지만 소품에 기록 키가 없습니다. 어떻게 고칠 수 있습니까?
Nicolas S.Xu

41
당신이없는 경우 this.props.history구성 요소에서 사용할 수있는 다음 수 import {withRouter} from 'react-router-dom'다음 export default withRouter(MyComponent)(또는 const MyComponent = withRouter(...)) 그리고 그것은 삽입합니다 history구성 요소의 소품에서 항목을 선택합니다.
Malvineous

@Malvineous thats funny, 이것에 대해 몰랐다! 시도해보십시오!
Jikku Jose

2
나는 근본적으로 무언가를 놓치고 있어야합니다. 왜냐하면 이것이 나를 위해 훌륭하게 작동하기 때문에 모든 답변에 왜 그렇게 긴 설명이 필요한지 전혀 알 수 없습니다.
Joshua Pinter

history.push클릭했을 때와 같이 컴포넌트가 다시 마운트되는 것을 방지 하고 업데이트를 트리거 하는 방법<Link>
Rahul Yadav

55

React-Router v4로 마이그레이션 할 때 비슷한 문제가 발생하여 아래에서 솔루션을 설명하려고 시도합니다.

이 답변을 문제를 해결하는 올바른 방법으로 생각하지 마십시오 .React Router v4가 성숙 해지고 베타 버전을 떠날 때 더 나은 결과가 발생할 가능성이 있다고 생각합니다 (이미 존재하더라도 발견하지 못했습니다) .

상황에 따라, 때때로 Redux-Saga사용자가 성공적으로 인증 할 때 기록 개체를 프로그래밍 방식으로 변경하는 데 사용 하기 때문에이 문제가 발생 했습니다.

React Router 문서에서 <Router> 구성 요소를 살펴보고 소품을 통해 자신의 기록 개체를 전달할 수 있음을 알 수 있습니다. 이것이 솔루션의 본질입니다. 우리React-Router전역 모듈 에서 히스토리 오브젝트제공합니다 .

단계 :

  1. 히스토리 npm 모듈 설치- yarn add history 또는 npm install history --save
  2. 레벨 폴더 history.js에 파일을 생성 하십시오 App.js(이것이 내 환경 설정이었습니다)

    // src/history.js
    
    import createHistory from 'history/createBrowserHistory';
    export default createHistory();`
  3. 이 히스토리 오브젝트를 라우터 컴포넌트에 다음과 같이 추가하십시오.

    // src/App.js
    
    import history from '../your/path/to/history.js;'
    <Router history={history}>
    // Route tags here
    </Router>
  4. 바로 가져 와서 예전처럼 URL을 조정 하여 글로벌 역사 개체를 :

    import history from '../your/path/to/history.js;'
    history.push('new/path/here/');

이제 모든 것이 동기화 상태를 유지해야하며 구성 요소 / 컨테이너를 통하지 않고 프로그래밍 방식으로 기록 개체를 설정하는 방법에 액세스 할 수 있습니다.


5
이 변경 사항은 저에게 효과적이지만 구성 요소 외부를 탐색하기 때문에 가능합니다. OP와 같은 구성 요소 내부를 탐색하는 경우 구성 요소가 전달한 소품을 사용하여 @rauliyohmc가 제안한 접근 방식을 사용합니다 Route.
Dan Ellis

2
이것은 08/17 현재 권장되는 접근법입니다
Spets

2
@Spets 필자의 경우, 이런 종류의 접근 방식을 사용하면 푸시 후 링크가 올바르게 업데이트되지만 구성 요소가 올바르게 렌더링되지 않습니다 (예 : 링크를 업데이트 한 후 페이지를 새로 고치지 않으면 구성 요소가 업데이트되지 않음). 이 방법이 권장되는 방법은 어디입니까? 링크 / 소스가 있습니까?
멋진

2
@ScottCoates 실제로 히스토리를 매개 변수로 제공하여 위의 예를 사용하여 정렬했지만 노드 모듈을 직접 디버깅 한 후. 최신 버전의 react-router-dom에 라우터라는 다른 객체가있을 때 "브라우저 히스토리를 라우터로 가져 오기"를 사용하여 웹 전체에서 흔히 발생하는 실수가 있습니다. 위의 예제에서 만든 기록과 함께 사용하면 정상적으로 작동합니다.
멋진

2
URL은 업데이트되지만 새 루트를 기준으로 페이지가 렌더링되지 않습니다. 어떤 해결책? 왜 트리거 경로가 그렇게 어려운가? 디자인 반응을하는 사람들은 마음에 없는가?
Nicolas S.Xu

43

TL; DR :

if (navigate) {
  return <Redirect to="/" push={true} />
}

간단하고 선언적인 대답은 다음 <Redirect to={URL} push={boolean} />과 함께 사용해야합니다 .setState()

push : boolean- true 인 경우 경로 재 지정은 현재 항목을 바꾸는 대신 새 항목을 내역으로 푸시합니다.


import { Redirect } from 'react-router'

class FooBar extends React.Component {
  state = {
    navigate: false
  }

  render() {
    const { navigate } = this.state

    // here is the important part
    if (navigate) {
      return <Redirect to="/" push={true} />
    }
   // ^^^^^^^^^^^^^^^^^^^^^^^

    return (
      <div>
        <button onClick={() => this.setState({ navigate: true })}>
          Home
        </button>
      </div>
    )
  }
}

여기에 전체 예제가 있습니다 . 자세한 내용은 여기를 참조 하십시오 .

추신. 이 예에서는 ES7 + Property Initializer 를 사용 하여 상태를 초기화합니다. 관심이 있으시면 여기도 보십시오 .


5
이 답변을 수락해야합니다. 가장 우아한 솔루션! @lustoykov +1
Ali Abbas Jaffri

1
내 버튼이 헤더에 있고 한 번만 탐색하면 componentDidUpdate에서 탐색을 다시 false로 설정했습니다.
peterorum

페이지가로드 될 때 리디렉션에 대해 알고있는 경우에만 작동합니다. 비동기 호출이 리턴되기를 기다리는 경우 (예 : Google 또는 다른 인증) history.push()메소드 중 하나를 사용해야 합니다.
brittohalloran 2016 년

실제로, <Redirect /> 구성 요소와 결합 된 반응의 선언적 특성을 여전히 활용할 수 있습니다. 페이지가로드되지 않으면 다른 <Redirect />로 대체 할 수 있습니다.
Lyubomir

@brittohalloran은 적절한 리액터 라우터를 사용하는이 방법의 아이디어이며, setState를 사용하여 다시 렌더링하도록합니다.
누군가 특별한

16

useHistory함수 구성 요소를 사용하는 경우 후크 사용

useHistory후크를 사용 하여 history인스턴스 를 얻을 수 있습니다 .

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

const MyComponent = () => {
  var history = useHistory();

  return (
    <button onClick={() => history.push("/about")}>
      Click me
    </button>
  );
}

useHistory후크 당신이 탐색하는 데 사용할 수 있다는 것을 역사 인스턴스에 액세스 할 수 있습니다.

history페이지 구성 요소 내에서 속성 사용

React Router history는 페이지 구성 요소를 포함한 일부 속성을 주입 합니다.

class HomePage extends React.Component {
  render() {
    const { history } = this.props;

    return (
      <div>
        <button onClick={() => history.push("/projects")}>
          Projects
        </button>
      </div>
    );
  }
}

하위 withRouter속성을 감싸서 라우터 속성을 주입

withRouter래퍼는 라우터 속성을 구성 요소에 주입합니다. 예를 들어,이 랩퍼를 사용하여 라우터를 주입하여 사용자 메뉴에 배치 된 단추 구성 요소를 로그 아웃 할 수 있습니다.

import { withRouter } from "react-router";

const LogoutButton = withRouter(({ history }) => {
  return (
    <button onClick={() => history.push("/login")}>
      Logout
    </button>
  );
});

export default LogoutButton;

11

props를 사용하여 히스토리 오브젝트에 액세스 할 수도 있습니다. this.props.history.push('new_url')


5
구성 요소에서 라우터에서 직접 내려온 경우에만 유용합니다. 히스토리 소품을이 기능이 필요한 모든 단일 구성 요소에 전달하지 않도록하십시오.
mwieczorek

3
당신이없는 경우 this.props.history구성 요소에서 사용할 수있는 다음 수 import {withRouter} from 'react-router-dom'다음 export default withRouter(MyComponent)(또는 const MyComponent = withRouter(...)) 그리고 그것은 삽입합니다 history구성 요소의 소품에서 항목을 선택합니다.
Malvineous

9

1 단계 : 가져올 항목이 하나뿐입니다.

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

2 단계 : 경로에서 기록을 전달합니다.

<Route
  exact
  path='/posts/add'
  render={({history}) => (
    <PostAdd history={history} />
  )}
/>

3 단계 : 내역은 다음 구성 요소에서 소품의 일부로 승인되므로 간단하게 다음을 수행 할 수 있습니다.

this.props.history.push('/');

그것은 쉽고 강력했습니다.


7

이것은 작동합니다 :

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

const SomeComponent = withRouter(({ history }) => (
    <div onClick={() => history.push('/path/some/where')}>
        some clickable element
    </div>); 
);

export default SomeComponent;

5

내 대답은 Alex 와 비슷합니다 . 왜 React-Router가 이것을 불필요하게 복잡하게 만들 었는지 잘 모르겠습니다. 본질적으로 글로벌에 액세스하기 위해 구성 요소를 HoC로 감싸 야하는 이유는 무엇입니까?

어쨌든, 그들이 어떻게 구현했는지 살펴보면 역사를<BrowserRouter> 둘러싼 작은 포장지 일뿐 입니다.

히스토리 비트를 꺼내어 어디에서나 가져올 수 있습니다. 그러나 트릭은 서버 측 렌더링을 수행 import하고 기록 모듈 을 시도하는 경우 브라우저 전용 API를 사용하기 때문에 작동하지 않습니다. 그러나 우리는 일반적으로 클릭 또는 다른 클라이언트 측 이벤트에 대한 응답으로 만 리디렉션하기 때문에 괜찮습니다. 따라서 가짜로해도 괜찮습니다.

// history.js
if(__SERVER__) {
    module.exports = {};
} else {
    module.exports = require('history').createBrowserHistory();
}

웹팩의 도움으로 우리는 몇 가지 변수를 정의하여 어떤 환경에 있는지 알 수 있습니다.

plugins: [
    new DefinePlugin({
        '__SERVER__': 'false',
        '__BROWSER__': 'true', // you really only need one of these, but I like to have both
    }),

그리고 지금 당신은 할 수 있습니다

import history from './history';

어디서나. 서버에서 빈 모듈을 반환합니다.

이러한 매직 변수를 사용하지 않으려면 require이벤트 핸들러 내부의 필요한 전역 객체 만 있으면됩니다 . import최상위 수준에서만 작동하기 때문에 작동하지 않습니다.


6
젠장 그들은 그것을 너무 복잡하게 만들었습니다.
Abhishek

4
나는 당신과 완전히 동의했다. 이것은 단지 탐색을 위해 너무 복잡합니다
Thai Tran

5

@rgommezz는 대부분의 경우에서 그것이 중요하다고 생각하는 경우를 제외하고 있다고 생각합니다.

// history is already a dependency or React Router, but if don't have it then try npm install save-dev history

import createHistory from "history/createBrowserHistory"

// in your function then call add the below 
const history = createHistory();
// Use push, replace, and go to navigate around.
history.push("/home");

이를 통해 구성 요소에 대해 많은 HoC를 수행하지 않고도 원하는 모든 구성 요소에서 탐색을 수행하기 위해 호출 할 수있는 작업 / 호출로 간단한 서비스를 작성할 수 있습니다 ...

왜 아무도이 솔루션을 이전에 제공하지 않았는지 명확하지 않습니다. 도움이 되길 바랍니다. 문제가 있으면 알려주세요.


4

나는 지금 며칠 동안 v4를 테스트하고 .. 나는 지금까지 그것을 사랑 해요! 잠시 후 의미가 있습니다.

나는 또한 같은 질문을했고 다음과 같이 가장 잘 작동하는 것처럼 그것을 다루는 것을 발견했습니다 (그리고 의도 된 방법 일 수도 있습니다). 상태, 삼항 연산자 및을 사용 <Redirect>합니다.

constructor ()에서

this.state = {
    redirectTo: null
} 
this.clickhandler = this.clickhandler.bind(this);

render ()에서

render(){
    return (
        <div>
        { this.state.redirectTo ?
            <Redirect to={{ pathname: this.state.redirectTo }} /> : 
            (
             <div>
               ..
             <button onClick={ this.clickhandler } />
              ..
             </div>
             )
         }

clickhandler ()에서

 this.setState({ redirectTo: '/path/some/where' });

도움이 되길 바랍니다. 알려주세요.


이 방법으로 함정이 있습니까? 내 프로젝트에서 생성자에서 상태를 설정할 때만 작동하며 거기에서 원하는 페이지로 리디렉션 할 수 있습니다. 그러나 이벤트 상태를 설정하면 (예 : 소품이 변경되었습니다) 새로운 상태로 호출 된 렌더 메소드가 표시되지만 리디렉션이 발생하지 않습니다. 같은 페이지가 표시됩니다.
Dmitry Malugin

함정은 역사를 대체 할 것이므로 반격 할 수 없으므로 기본적으로 이것은 좋은 해결책이 아닙니다.
dannytenaglias

4

ReactJS는 웹 응용 프로그램을 작성하는 방법과 완전히 다른 방식이기 때문에 아주 간단하지만 복잡합니다. 노인들에게는 매우 외계인입니다!

혼란을 없애기 위해 별도의 구성 요소를 만들었습니다.

// LinkButton.js

import React from "react";
import PropTypes from "prop-types";
import {Route} from 'react-router-dom';

export default class LinkButton extends React.Component {

    render() {
        return (
            <Route render={({history}) => (
                <button {...this.props}
                       onClick={() => {
                           history.push(this.props.to)
                       }}>
                    {this.props.children}
                </button>
            )}/>
        );
    }
}

LinkButton.propTypes = {
    to: PropTypes.string.isRequired
};

그런 다음 render()메소드에 추가하십시오 .

<LinkButton className="btn btn-primary" to="/location">
    Button Text
</LinkButton>

이 솔루션이 매우 유용하다는 것을 알았습니다. 코드를 복사하고 있습니다. 당신이 github에 넣었다는 것을 알려주세요. 나는 당신에게 직접 기여할 것입니다.
Abhinav Manchanda

3

이 끔찍한 디자인을 다루는 다른 방법이 없기 때문에 withRouter HOC 접근 방식 을 사용하는 일반적인 구성 요소를 작성했습니다 . 아래 예제는 button요소를 래핑하는 것이지만 필요한 클릭 가능한 요소로 변경할 수 있습니다.

import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';

const NavButton = (props) => (
  <Button onClick={() => props.history.push(props.to)}>
    {props.children}
  </Button>
);

NavButton.propTypes = {
  history: PropTypes.shape({
    push: PropTypes.func.isRequired
  }),
  to: PropTypes.string.isRequired
};

export default withRouter(NavButton);

용법:

<NavButton to="/somewhere">Click me</NavButton>

3
this.props.history.push("/url")

구성 요소에서 this.props.history를 찾을 수 없으면 다음을 시도하십시오.

import {withRouter} from 'react-router-dom'
export default withRouter(MyComponent)  

정말 고마워!
QauseenMZ

1

때로는 응용 프로그램과 버튼으로 경로를 전환하는 것을 선호하기 때문에 이것은 저에게 효과적인 최소한의 예제입니다.

import { Component } from 'react'
import { BrowserRouter as Router, Link } from 'react-router-dom'

class App extends Component {
  constructor(props) {
    super(props)

    /** @type BrowserRouter */
    this.router = undefined
  }

  async handleSignFormSubmit() {
    await magic()
    this.router.history.push('/')
  }

  render() {
    return (
      <Router ref={ el => this.router = el }>
        <Link to="/signin">Sign in</Link>
        <Route path="/signin" exact={true} render={() => (
          <SignPage onFormSubmit={ this.handleSignFormSubmit } />
        )} />
      </Router>
    )
  }
}

0

완전히 사용하여 라우터를 initalizing 전에 리디렉션이 필요한 분들을 위해 React Router또는 React Router Dom당신은 단순히 역사의 객체를 accesing과 당신의 constructur 내에서에 새로운 상태를 밀어 리디렉션을 제공 할 수 있습니다 app.js. 다음을 고려하세요:

function getSubdomain(hostname) {
    let regexParse = new RegExp('[a-z\-0-9]{2,63}\.[a-z\.]{2,5}$');
    let urlParts = regexParse.exec(hostname);
    return hostname.replace(urlParts[0], '').slice(0, -1);
}

class App extends Component {

    constructor(props) {
        super(props);


        this.state = {
            hostState: true
        };

        if (getSubdomain(window.location.hostname).length > 0) {
            this.state.hostState = false;
            window.history.pushState('', '', './login');
        } else {
            console.log(getSubdomain(window.location.hostname));
        }

    }


    render() {
        return (

            <BrowserRouter>
                {this.state.hostState ? (
                    <div>
                        <Route path="/login" component={LoginContainer}/>
                        <Route path="/" component={PublicContainer}/>
                    </div>
                ) : (
                    <div>
                        <Route path="/login" component={LoginContainer}/>
                    </div>
                )

                }
            </BrowserRouter>)
    }


}

여기서 컴포넌트가 렌더링되기 전에 히스토리 오브젝트와 상호 작용하여 서브 도메인에 종속 된 출력 라우트를 변경하려고합니다. 경로를 그대로두고 경로를 효과적으로 재 지정할 수 있습니다.

window.history.pushState('', '', './login');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.