react-router v4에서 기록을 얻는 방법은 무엇입니까?


103

React-Router v3에서 v4로 마이그레이션하는 데 약간의 문제가 있습니다. v3에서는 어디서든이 작업을 수행 할 수있었습니다.

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

v4에서 어떻게 이것을 달성합니까?

withRouter컴포넌트에있을 때 hoc , 반응 컨텍스트 또는 이벤트 라우터 소품을 사용할 수 있다는 것을 알고 있습니다. 하지만 나에게는 그렇지 않습니다.

v4에서 NavigatingOutsideOfComponents 의 동등성을 찾고 있습니다.


1
@Chris에게 감사하지만 내가 말했듯이 나는 Component에 없습니다.
storm_buster

유틸리티 클래스 @ 크리스가 확인하시기 바랍니다 github.com/ReactTraining/react-router/blob/master/docs/guides/...를 , 그것은 그 밖에 REDUX middlewarere 또는 아무것도 수 있었다
storm_buster


결국 BrowserRouter를 루트 구성 요소로 사용했습니다. 그런 식으로 App 구성 요소를 Router와 함께 사용할 수 있습니다. 정확히 무엇을 요청했는지는 아니지만 동일한 요구 사항이 있으며 이것으로 충분합니다.
The Fool

답변:


182

history객체 를 내보내는 모듈 만 있으면됩니다 . 그런 다음 프로젝트 전체에서 해당 개체를 가져옵니다.

// history.js
import { createBrowserHistory } from 'history'

export default createBrowserHistory({
  /* pass a configuration object here if needed */
})

그런 다음 내장 라우터 중 하나를 사용하는 대신 <Router>구성 요소를 사용합니다 .

// index.js
import { Router } from 'react-router-dom'
import history from './history'
import App from './App'

ReactDOM.render((
  <Router history={history}>
    <App />
  </Router>
), holder)
// some-other-file.js
import history from './history'
history.push('/go-here')

1
감사합니다! 현재 react-router4를 사용하여이 가져 오기를 history.js에서 사용해야했습니다. import createBrowserHistory from 'history / createBrowserHistory';
peter.bartos

3
Route에 history = {history}를 넣고 소품처럼 지나갈 때 효과가있었습니다.
Nath Paiva 2017 년

1
withHistory를 사용하여 별도의 파일을 생성하는 대신 소품에서 히스토리를 가져올 수 있습니다. 이 솔루션은 redux와 함께 작동하지 않았습니다.
Zeel Shah

4
가져 오기 createHashHistory사용 된 경우 HashRouter.
David Harkness

2
@HassanAzzam 아마도 react-router V5를 사용하고 있으며이 답변은 V5가 아닌 V4에서 작동합니다. 나는 지금 똑같은 도전을하고 있고 모든 곳을 찾고 있지만 그것을 작동시킬 수는 없습니다. 구성 요소 외부의 history.push가 작동하지만 링크를 클릭하면 더 이상 작동하지 않습니다.
Waterlink

71

작동합니다! https://reacttraining.com/react-router/web/api/withRouter

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

class MyComponent extends React.Component {
  render () {
    this.props.history;
  }
}

withRouter(MyComponent);

27
구성 요소에있는 한. 나는 구성 요소에 아닙니다
storm_buster

1
감사합니다. 이것은 구성 요소에서 다른 경로로 연결하는 가장 쉽고 간단한 방법입니다. 나는 this.props.history.push('/some_route');그것이 작동하기 위해 당신이해야 할 필요가 있다고 덧붙일 것입니다.
dannytenaglias

1
@storm_buster const Component = props => {... // stuff}export default withRouter(Component)상태 비 저장 구성 요소에 나를 위해 작품
칼 테일러

11

허용 대답 Similiary 당신이 할 수있는 것은 사용하는 것입니다 reactreact-router자체는 당신이 제공하는 history어떤 개체는 다음 파일의 범위와 수출을 할 수 있습니다.

history.js

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

// variable which will point to react-router history
let globalHistory = null;

// component which we will mount on top of the app
class Spy extends React.Component {
  constructor(props) {
    super(props)
    globalHistory = props.history; 
  }

  componentDidUpdate() {
    globalHistory = this.props.history;
  }

  render(){
    return null;
  }
}

export const GlobalHistory = withRouter(Spy);

// export react-router history
export default function getHistory() {    
  return globalHistory;
}

그런 다음 나중에 구성 요소를 가져오고 마운트하여 기록 변수를 초기화합니다.

import { BrowserRouter } from 'react-router-dom';
import { GlobalHistory } from './history';

function render() {
  ReactDOM.render(
    <BrowserRouter>
        <div>
            <GlobalHistory />
            //.....
        </div>
    </BrowserRouter>
    document.getElementById('app'),
  );
}

그런 다음 마운트 된 앱에서 가져올 수 있습니다.

import getHistory from './history'; 

export const goToPage = () => (dispatch) => {
  dispatch({ type: GO_TO_SUCCESS_PAGE });
  getHistory().push('/success'); // at this point component probably has been mounted and we can safely get `history`
};

나는 심지어 그것을하는 npm 패키지 를 만들었습니다 .


reactjs 16.9부터이 솔루션은 componentWillMount 및 componentWillReceiveProps에 대한 지원 중단 경고를 표시합니다.
이안

1
사실 @ian 고정이
토마스 Mularczyk


4

근거로 이 답변 만을 위해 다른 구성 요소에 대한 탐색에 역사 개체를 필요로하는 경우 :

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

function HomeButton() {
  const history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

잘못되었습니다. 구성 요소 내에 있습니다. // 수락 된 답변에서 some-other-file.js 참조
storm_buster

0

App.js에서

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

 const TheContext = React.createContext(null);

 const App = () => {
   const history = useHistory();

   <TheContext.Provider value={{ history, user }}>

    <Switch>
        <Route exact path="/" render={(props) => <Home {...props} />} />
        <Route
          exact
          path="/sign-up"
          render={(props) => <SignUp {...props} setUser={setUser} />}
        /> ...

그런 다음 하위 구성 요소에서 :

const Welcome = () => {
    
    const {user, history} = React.useContext(TheContext); 
    ....

-2

의 특정 사례 react-router에서 using context은 유효한 사례 시나리오입니다. 예 :

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

  render () {
    this.context.router;
  }
}

라우터 컨텍스트를 통해 히스토리 인스턴스에 액세스 할 수 있습니다 (예 : this.context.router.history.


질문은 특히 언제 컴포넌트 외부에 있는지 묻는 것이므로 this.context는 옵션으로 사용할 수 없습니다.> "나는 컴포넌트에있을 때 내가 사용할 수있는 hoc withRouter, 반응 컨텍스트 또는 이벤트 라우터 props를 알고 있습니다. 저에게는 그렇지 않습니다. "
SunshinyDoyle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.