react-router 페이지로 돌아 가기 기록을 어떻게 구성합니까?


121

누구든지 특정 경로가 아닌 이전 페이지로 돌아가는 방법을 알려주시겠습니까?

이 코드를 사용하는 경우 :

var BackButton = React.createClass({

 mixins: [Router.Navigation],
  render: function() {
    return (
        <button
            className="button icon-left"
            onClick={this.navigateBack}>
            Back
        </button>
    );
  },

  navigateBack: function(){
    this.goBack();
  }
});

이 오류가 발생했습니다. 라우터 기록이 없기 때문에 goBack ()이 무시되었습니다.

내 경로는 다음과 같습니다.

// Routing Components
Route = Router.Route;
RouteHandler = Router.RouteHandler;
DefaultRoute = Router.DefaultRoute;

var routes = (
 <Route name="app" path="/" handler={OurSchoolsApp}>
     <DefaultRoute name="home" handler={HomePage} />
     <Route name="add-school" handler={AddSchoolPage}  />
     <Route name="calendar" handler={CalendarPage}  />
     <Route name="calendar-detail" path="calendar-detail/:id" handler={CalendarDetailPage} />
     <Route name="info-detail" path="info-detail/:id" handler={InfoDetailPage} />
     <Route name="info" handler={InfoPage} />
     <Route name="news" handler={NewsListPage} />
     <Route name="news-detail" path="news-detail/:id" handler={NewsDetailPage} />
     <Route name="contacts" handler={ContactPage} />
     <Route name="contact-detail" handler={ContactDetailPage} />
     <Route name="settings" handler={SettingsPage} />
 </Route>
 );

 Router.run(routes, function(Handler){
   var mountNode = document.getElementById('app');
   React.render(<Handler /> , mountNode);
 });

해결책을 찾았다면 여기에서 공유해 주시겠습니까? 감사.
user261002 jul.

답변:


43

다음과 같이 초기화하여 라우터에서 BrowserHistory를 활성화하면됩니다 <Router history={new BrowserHistory}>.

그 전에 다음 BrowserHistory에서 요구해야합니다 .'react-router/lib/BrowserHistory'

도움이 되었기를 바랍니다.

업데이트 : ES6의 예

const BrowserHistory = require('react-router/lib/BrowserHistory').default;

const App = React.createClass({
    render: () => {
        return (
            <div><button onClick={BrowserHistory.goBack}>Go Back</button></div>
        );
    }
});

React.render((
    <Router history={BrowserHistory}>
        <Route path="/" component={App} />
    </Router>
), document.body);

안녕하세요, 우리는 같은 문제에 직면하고 있습니다. 자세히 설명해 주시겠습니까? 감사합니다
user261002 2015-07-13

23
이것이 어떻게 정답입니까? 이것은 질문에 대한 답도 아닙니다. @bomber
GN.

14
이것을 읽는 사람을 위해. 하위 구성 요소에서이 작업을 수행하려는 경우. 에서 히스토리 개체를 찾을 수 있습니다 this.props.history. 그래서, 코드가된다this.props.history.goBack
Sisir

3
반응 라우터 4는 어떻습니까? 더 이상 BrowserHistory를 지원하지 않는다고 생각합니다.
Akshay Lokur

1
react-router-dom 버전 5에서 히스토리는 BrowserRouter에 의해 암시 적으로 생성되고 props를 통해 사용할 수 있으며 props.history를 통해 액세스 할 수 있습니다.
Srikanth Kyatham

97

React v16 및 ​​ReactRouter v4.2.0으로 업데이트 (2017 년 10 월) :

class BackButton extends Component {
  static contextTypes = {
    router: () => true, // replace with PropTypes.object if you use them
  }

  render() {
    return (
      <button
        className="button icon-left"
        onClick={this.context.router.history.goBack}>
          Back
      </button>
    )
  }
}

React v15 및 ReactRouter v3.0.0으로 업데이트 (2016 년 8 월) :

var browserHistory = ReactRouter.browserHistory;

var BackButton = React.createClass({
  render: function() {
    return (
      <button
        className="button icon-left"
        onClick={browserHistory.goBack}>
        Back
      </button>
    );
  }
});

임베디드 iframe을 사용하여 좀 더 복잡한 예제로 바이올린을 만들었습니다 : https://jsfiddle.net/kwg1da3a/

React v14 및 ReacRouter v1.0.0 (2015 년 9 월 10 일)

다음과 같이 할 수 있습니다.

var React = require("react");
var Router = require("react-router");

var SomePage = React.createClass({
  ...

  contextTypes: {
    router: React.PropTypes.func
  },
  ...

  handleClose: function () {
    if (Router.History.length > 1) {
      // this will take you back if there is history
      Router.History.back();
    } else {
      // this will take you to the parent route if there is no history,
      // but unfortunately also add it as a new route
      var currentRoutes = this.context.router.getCurrentRoutes();
      var routeName = currentRoutes[currentRoutes.length - 2].name;
      this.context.router.transitionTo(routeName);
    }
  },
  ...

돌아가는 데 필요한 이력이 있는지주의해야합니다. 페이지를 직접 클릭 한 다음 다시 클릭하면 앱 이전의 브라우저 기록으로 돌아갑니다.

이 솔루션은 두 시나리오를 모두 처리합니다. 그러나 뒤로 버튼을 사용하여 페이지 내에서 탐색하고 브라우저 기록에 추가 할 수있는 iframe은 처리하지 않습니다. 솔직히 나는 그것이 react-router의 버그라고 생각합니다. 여기에 생성 된 문제 : https://github.com/rackt/react-router/issues/1874


컨텍스트를 사용하지 않고 이렇게 할 수있는 방법이 있다면 좋을까요?
Adam D

1
또한 설정에 따라 this.context.router.history.goBack 대신 this.props.history.goBack을 사용할 수 있습니다.
PhoenixB

54
  1. 수입 withRouter

    import { withRouter } from 'react-router-dom';
  2. 구성 요소를 다음과 같이 내 보냅니다.

    export withRouter(nameofcomponent) 
  3. 예를 들어 버튼을 클릭하면 다음을 호출합니다 goBack.

    <button onClick={this.props.history.goBack}>Back</button>

react-router-domv4.3에서 테스트 됨


2
BTW 가져 오기 또는 사용하지 않고도 나를 위해 작동합니다 withRouter. 브라우저 기록 네이티브 API를 사용하고있을 수도 있습니다. 하지만 괜찮습니까 ??
Gianfranco P.

1
그것은 좋은 해결책입니다. 사용자가 직접 URL을 사용하여 페이지를 방문 할 때 유일한 문제-> 기록이 없기 때문에 앱이 중단됩니다.
skryvets

2
여기에 최고의 설명
Z_z_Z

@MichaelFreidgeim 당신은 당신의 코드 스 니펫을 업로드 해 주시겠습니까? 그래서 내가 확인하고 확인
하겠습니다


32

반응 라우터, 상태 비 저장 기능을 사용하는 믹스 인이없는 ES6 방법.

import React from 'react'
import { browserHistory } from 'react-router'

export const Test = () => (
  <div className="">
    <button onClick={browserHistory.goBack}>Back</button>
  </div>
)

3
솔루션을하려고 할 때 나는 브라우저 경고를 얻을 :export 'browserHistory' was not found in 'react-router'
랄프 데이비드 애 버나

2
browserHistory는 v2 및 v3에만 있습니다. v4를 사용하는 경우 마이그레이션 가이드를 읽어야합니다. github.com/ReactTraining/react-router/blob/…
ptorsson

@Ralp,이 오류 메시지가 표시되면 다음을 확인하십시오. stackoverflow.com/questions/49787659/…
Miles M.

13

React Hooks 사용

수입:

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

상태 비 저장 구성 요소 :

  let history = useHistory();

이벤트

history.goBack()

<button onClick = {() => history.goBack ()}> 뒤로 </ button>
Hunter

나는 후크를 좋아하기 때문에 이것을 언급 해 주셔서 감사합니다. 지금까지 withRouter를 사용하고 있습니다.
newman

10

React-router v4 Live Example 과 함께 React 16.0을 사용한 작업 예제를 확인하십시오 . 코드 Github 확인

사용 withRouterhistory.goBack()

이것이 내가 구현하는 아이디어입니다 ...

History.js

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'
import './App.css'


class History extends Component {

  handleBack = () => {
    this.props.history.goBack()
  }

  handleForward = () => {
    console.log(this.props.history)
    this.props.history.go(+1)
  }

  render() {
    return <div className="container">
      <div className="row d-flex justify-content-between">
        <span onClick={this.handleBack} className="d-flex justify-content-start button">
          <i className="fas fa-arrow-alt-circle-left fa-5x"></i>
        </span>
        <span onClick={this.handleForward} className="d-flex justify-content-end button">
          <i className="fas fa-arrow-alt-circle-right fa-5x"></i>
        </span>
      </div>
    </div>
  }
}

export default withRouter(History)

PageOne.js

import React, { Fragment, Component } from 'react'

class PageOne extends Component {

   componentDidMount(){
      if(this.props.location.state && this.props.location.state.from != '/pageone')
      this.props.history.push({
         pathname: '/pageone',
         state: { 
             from: this.props.location.pathname
         }
       });
   }

   render() {
      return (
         <Fragment>
            <div className="container-fluid">
               <div className="row d-flex justify-content-center">
                  <h2>Page One</h2>
               </div>
            </div>
         </Fragment>
      )
   }
}

export default PageOne

추신 코드가 여기에 모두 게시하는 것이 큰 죄송합니다.


1
이것은 '19 년에 받아 들여진 대답이어야합니다. React Router는 "withRouter"라는 고차 구성 요소 (HOC)를 제공하므로 구성 요소를 래핑하여 기록 및 위치와 같은 소품에 액세스 할 수 있습니다.

1
예, 구성 요소를 래핑 할 때 HOC의 withRouter에서와 같이 기록 및 위치 데이터를 제공합니다. 도전적인 것은 계속 읽고 절대 안주하지 않습니다.
Anupam Maurya

go함수에 더하기 기호를 전달하는 이유를 물어봐도 history.go(+1)될까요? history.go(1)충분해야합니다.
gion_13

10

이것은 브라우저 및 해시 기록과 함께 작동합니다.

this.props.history.goBack();

8

이것은 작동하는 BackButton 구성 요소 (React 0.14)입니다.

var React = require('react');
var Router = require('react-router');

var History = Router.History;

var BackButton = React.createClass({
  mixins: [ History ],
  render: function() {
    return (
      <button className="back" onClick={this.history.goBack}>{this.props.children}</button>
    );
  }
});

module.exports = BackButton;

역사가 없다면 다음과 같이 할 수 있습니다.

<button className="back" onClick={goBack}>{this.props.children}</button>

function goBack(e) {
  if (/* no history */) {
    e.preventDefault();
  } else {
    this.history.goBack();
  }
}

7

react-router v2.x의 경우 변경되었습니다. ES6를 위해 제가하는 일은 다음과 같습니다.

import React from 'react';
import FontAwesome from 'react-fontawesome';
import { Router, RouterContext, Link, browserHistory } from 'react-router';

export default class Header extends React.Component {

  render() {
    return (
      <div id="header">
        <div className="header-left">
          {
            this.props.hasBackButton &&
            <FontAwesome name="angle-left" className="back-button" onClick={this.context.router.goBack} />
          }
        </div>
        <div>{this.props.title}</div>
      </div>
    )
  }
}

Header.contextTypes = {
  router: React.PropTypes.object
};

Header.defaultProps = {
  hasBackButton: true
};

Header.propTypes = {
  title: React.PropTypes.string
};

5

에서 반응 라우터가 사용할 수있는 4.x 버전 history.goBack에 해당한다 history.go(-1).

App.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";

const styles = {
  fontFamily: "sans-serif",
  textAlign: "left"
};

const App = () => (
  <div style={styles}>
    <Router>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/contact">Contact</Link></li>
        </ul>

        <hr />

        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />

        <Back />{/* <----- This is component that will render Back button */}
      </div>
    </Router>
  </div>
);

render(<App />, document.getElementById("root"));

Back.js

import React from "react";
import { withRouter } from "react-router-dom";

const Back = ({ history }) => (
  <button onClick={history.goBack}>Back to previous page</button>
);

export default withRouter(Back);

데모 : https://codesandbox.io/s/ywmvp95wpj

방문자가 응용 프로그램을 열기 전에 방문한 페이지를로드 history할 수 있기 때문에 사용자 를 사용 하여 떠날 history.goBack()수 있습니다.


위에서 설명한 상황을 방지하기 위해 사용자의 마지막 위치를 감시 하는 간단한 라이브러리 react-router-last-location 을 만들었습니다 .

사용법은 매우 간단합니다. 먼저 설치해야합니다.react-router-dom 하고 react-router-last-location부터 npm.

npm install react-router-dom react-router-last-location --save

그런 다음 LastLocationProvider아래와 같이 사용하십시오 .

App.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { LastLocationProvider } from "react-router-last-location";
//              ↑
//              |
//              |
//
//       Import provider
//
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";

const styles = {
  fontFamily: "sans-serif",
  textAlign: "left"
};

const App = () => (
  <div style={styles}>
    <h5>Click on About to see your last location</h5>
    <Router>
      <LastLocationProvider>{/* <---- Put provider inside <Router> */}
        <div>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
            <li><Link to="/contact">Contact</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />

          <Back />
        </div>
      </LastLocationProvider>
    </Router>
  </div>
);

render(<App />, document.getElementById("root"));

Back.js

import React from "react";
import { Link } from "react-router-dom";
import { withLastLocation } from "react-router-last-location";
//              ↑
//              |
//              |
//
//    `withLastLocation` higher order component
//    will pass `lastLocation` to your component               
//
//                   |
//                   |
//                   ↓
const Back = ({ lastLocation }) => (
  lastLocation && <Link to={lastLocation || '/'}>Back to previous page</Link>
);


//          Remember to wrap
//   your component before exporting
//
//                   |
//                   |
//                   ↓
export default withLastLocation(Back);

데모 : https://codesandbox.io/s/727nqm99jj


LastLocation 객체를 필요한 구성 요소에 어떻게 끌어들일까요? 즉, 예제와 같은 일부 출력 출력 대신 프로그래밍 방식으로 사용하고 싶습니다. if (lastLocation == 'about')
dmayo

내가 당신을 올바르게 이해했는지 확실하지 않으므로 내가 틀렸다면 나를 수정하십시오. lastLocationReact 외부 에서 사용 하시겠습니까 , 아니면 I'd like to use it programmatically다음과 같이 가져 오는 기능을 원 import { lastLocation } from '...'하십니까?
hinok

5

나를 위해 일한 것은 내 파일 맨 위에 withRouter를 가져 오는 것이 었습니다.

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

그런 다음 내 파일 하단에 내 보낸 함수를 래핑하는 데 사용합니다.

export default withRouter(WebSitePageTitleComponent)

그런 다음 라우터의 내역 소품에 액세스 할 수있었습니다. 아래 전체 샘플 코드!

import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'

import PropTypes from 'prop-types'

class TestComponent extends Component {
  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    event.preventDefault()
    this.props.history.goBack()
  }

  render() {
    return (
      <div className="page-title">
        <a className="container" href="/location" onClick={this.handleClick}>
          <h1 className="page-header">
            { this.props.title }
          </h1>
        </a>
      </div>
    )
  }
}

const { string, object } = PropTypes

TestComponent.propTypes = {
  title: string.isRequired,
  history: object
}

export default withRouter(TestComponent)

5

특정 페이지로 돌아 가기 :

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

  const history = useHistory();
  
  const routeChange = () => {
    let path = '/login';
    history.push(path);
  };

이전 페이지로 돌아 가기 :

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

  const history = useHistory();
  
  const routeChange = () => {
    history.goBack()
  };

2
감사합니다, 이것은 훌륭한 2020 답변입니다! 수락 된 답변은 2015
이었습니다

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

this.props.history.goBack();

이 버전을 사용하고 있습니다.

"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",

2

나를 위해 일한 유일한 해결책은 가장 간단했습니다. 추가 수입이 필요하지 않습니다.

<a href="#" onClick={() => this.props.history.goBack()}>Back</a>

Tks, IamMHussain


아주 좋아. 단순하고 겸손한
Dinesh Kanivu

1

다음과 같이 구성 요소를 호출하십시오.

<BackButton history={this.props.history} />

다음은 구성 요소입니다.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
class BackButton extends Component {
  constructor() {
    super(...arguments)

    this.goBack = this.goBack.bind(this)
  }

  render() {
    return (
      <button
        onClick={this.goBack}>
          Back
      </button>
    )
  }

  goBack() {
    this.props.history.goBack()
  }
}

BackButton.propTypes = {
  history: PropTypes.object,
}

export default BackButton

나는 사용하고있다 :

"react": "15.6.1"
"react-router": "4.2.0"

1

리덕스

당신은 또한 사용할 수 react-router-redux있습니다있는 goBack()push().

다음은이를위한 샘플러 팩입니다.

앱의 진입 점에는이 필요 ConnectedRouter하며 때로는 연결하기 까다로운 연결이 history객체입니다. Redux 미들웨어는 기록 변경 사항을 수신합니다.

import React from 'react'
import { render } from 'react-dom'
import { ApolloProvider } from 'react-apollo'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import client from './components/apolloClient'
import store, { history } from './store'
import Routes from './Routes'
import './index.css'

render(
  <ApolloProvider client={client}>
    <Provider store={store}>
      <ConnectedRouter history={history}>
        <Routes />
      </ConnectedRouter>
    </Provider>
  </ApolloProvider>,
  document.getElementById('root'),
)

를 연결하는 방법을 보여 드리겠습니다 history. 히스토리를 스토어로 가져오고 앱의 진입 점에서 사용할 수 있도록 싱글 톤으로 내보내는 방법을 확인합니다.

import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers'

export const history = createHistory()

const initialState = {}
const enhancers = []
const middleware = [thunk, routerMiddleware(history)]

if (process.env.NODE_ENV === 'development') {
  const { devToolsExtension } = window
  if (typeof devToolsExtension === 'function') {
    enhancers.push(devToolsExtension())
  }
}

const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers)
const store = createStore(rootReducer, initialState, composedEnhancers)

export default store

위의 예제 블록은 react-router-redux설정 프로세스를 완료하는 미들웨어 헬퍼 를로드하는 방법을 보여줍니다 .

이 다음 부분은 완전히 추가적이라고 생각하지만 미래의 누군가가 혜택을 찾을 경우를 대비하여 포함하겠습니다.

import { combineReducers } from 'redux'
import { routerReducer as routing } from 'react-router-redux'

export default combineReducers({
  routing, form,
})

routerReducer일반적으로 .NET으로 인해 발생하지 않는 구성 요소를 강제로 다시로드 할 수 있기 때문에 항상 사용 합니다 shouldComponentUpdate. 명백한 예는 사용자가 NavLink버튼을 누를 때 업데이트되어야하는 Nav Bar가있는 경우 입니다. 그 길을 따라 가면 Redux의 연결 방법이 shouldComponentUpdate. 을 사용 routerReducer하면을 사용 mapStateToProps하여 경로 변경 사항을 탐색 모음에 매핑 할 수 있으며이 기능은 기록 객체가 변경 될 때 업데이트되도록 트리거합니다.

이렇게 :

const mapStateToProps = ({ routing }) => ({ routing })

export default connect(mapStateToProps)(Nav)

사람들을 위해 추가 키워드를 추가하는 동안 용서하십시오. 구성 요소가 제대로 업데이트되지 않으면 shouldComponentUpdate연결 기능을 제거하여 조사 하고 문제가 해결되는지 확인하십시오. 그렇다면을 가져 routerReducer오면 URL이 변경 될 때 구성 요소가 제대로 업데이트됩니다.

끝으로, 모든 것을 수행 한 후, 당신은 호출 할 수 있습니다 goBack()또는 push()언제든지 당신이 원하는!

임의의 구성 요소에서 지금 시도하십시오.

  1. 가져 오기 connect()
  2. 당신도 필요하지 않습니다 mapStateToProps또는mapDispatchToProps
  3. goBack에서 가져 오기 및 푸시 react-router-redux
  4. 요구 this.props.dispatch(goBack())
  5. 요구 this.props.dispatch(push('/sandwich'))
  6. 긍정적 인 감정을 경험하십시오

더 많은 샘플링이 필요하면 https://www.npmjs.com/package/react-router-redux를 확인 하십시오.


1

이렇게 사용하면됩니다

<span onClick={() => this.props.history.goBack()}>Back</span>

0

이 코드는 당신을 위해 트릭을 할 것입니다.

this.context.router.history.goBack()

0

React Router v6

useNavigate Hook은 지금 돌아가는 데 권장되는 방법입니다.

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

function App() {
  const navigate = useNavigate();

  return (
    <>
      <button onClick={() => navigate(-1)}>go back</button>
      <button onClick={() => navigate(1)}>go forward</button>
    </>
  );
}

Codesandbox 샘플

여러 내역 스택 항목 뒤로 / 앞으로 이동 :
<button onClick={() => navigate(-2)}>go two back</button>
<button onClick={() => navigate(2)}>go two forward</button>
특정 경로로 이동 :
navigate("users") // go to users route, like history.push
navigate("users", { replace: true }) // go to users route, like history.replace
navigate("users", { state }) // go to users route, pass some state in

useNavigate 을 대체이 useHistory 하는 지원 곧이 서스펜스 / 동시 모드 더 반응한다.


나는 이것을 시도했지만 오류가 발생했습니다.Attempted import error: 'useNavigate' is not exported from 'react-router-dom'.
Geek

1
@Geek 좋은 캐치. 를 사용 v6.0.0-beta.0하여 개발자는 history패키지를 피어 종속성으로 만들었습니다 . 이제 다시 작동하는 업데이트 된 Codesandbox를 살펴보십시오.
ford04

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