Bagaimana cara mendapatkan riwayat di react-router v4?

103

Saya mengalami sedikit masalah saat bermigrasi dari React-Router v3 ke v4. di v3 saya bisa melakukan ini di mana saja:

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

Bagaimana cara mencapai ini di v4.

Saya tahu bahwa saya dapat menggunakan, hoc withRouter, konteks reaksi, atau alat peraga router acara ketika Anda berada dalam sebuah Komponen. tetapi tidak demikian halnya bagi saya.

Saya mencari kesetaraan NavigatingOutsideOfComponents di v4

storm_buster
sumber
1
Terima kasih @ Chris, tapi seperti yang saya katakan, saya tidak berada di Komponen.
storm_buster
@Chris di kelas utilitas, silakan periksa github.com/ReactTraining/react-router/blob/master/docs/guides/… , itu bisa jadi redux middlewarere atau apa pun
storm_buster
cara termudah stackoverflow.com/a/53916596/3966458
Saahithyan Vigneswaran
Saya akhirnya menggunakan BrowserRouter sebagai komponen root. Dengan cara itu saya bisa menggunakan komponen App withRouter. Tidak persis seperti yang Anda minta tetapi saya memiliki persyaratan yang sama dan ini cukup untuk saya.
The Fool

Jawaban:

182

Anda hanya perlu memiliki modul yang mengekspor historyobjek. Kemudian Anda akan mengimpor objek itu ke seluruh proyek Anda.

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

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

Kemudian, alih-alih menggunakan salah satu router internal, Anda akan menggunakan <Router>komponen.

// 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')
Paul S
sumber
1
Terima kasih banyak! Saat ini, menggunakan react-router4, saya harus menggunakan impor ini di history.js sebagai gantinya: import createBrowserHistory dari 'history / createBrowserHistory';
peter.bartos
3
Ini berhasil bagi saya ketika saya meletakkan sejarah = {sejarah} di Route dan lulus seperti alat peraga
Nath Paiva
1
kita bisa menggunakan withHistory dan mendapatkan history di props daripada membuat file terpisah. solusi ini tidak berhasil untuk saya dengan redux.
Zeel Shah
4
Impor createHashHistoryjika Anda menggunakan HashRouter.
David Harkness
2
@HassanAzzam Anda mungkin menggunakan react-router V5, dan jawaban ini berfungsi untuk V4, bukan V5. Saya sekarang memiliki tantangan yang sama, dan saya mencari ke mana-mana, tetapi tidak dapat membuatnya berhasil. history.push di luar komponen berfungsi, tetapi klik pada Tautan tidak lagi.
Waterlink
71

Ini bekerja! 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);
Justin Yueh
sumber
27
selama Anda berada dalam sebuah komponen. Saya tidak berada dalam komponen
storm_buster
1
Terima kasih, ini adalah cara termudah dan paling mudah untuk menautkan ke rute lain dari sebuah komponen. Saya hanya akan menambahkan bahwa Anda perlu melakukannya this.props.history.push('/some_route');agar dapat berfungsi.
dannytenaglias
1
@storm_buster const Component = props => {... // stuff}dan export default withRouter(Component)bekerja untuk saya pada komponen tanpa kewarganegaraan
Karl Taylor
11

Mirip dengan jawaban yang diterima, apa yang dapat Anda lakukan adalah menggunakan reactdan react-routeritu sendiri untuk memberi Anda historyobjek yang dapat Anda lingkupi dalam file dan kemudian ekspor.

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;
}

Anda kemudian mengimpor Komponen dan memasang untuk menginisialisasi variabel riwayat:

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

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

Dan kemudian Anda bisa mengimpor aplikasi Anda ketika sudah terpasang:

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`
};

Saya bahkan membuat dan paket npm yang melakukan hal itu.

Tomasz Mularczyk
sumber
Mulai reactjs 16.9, solusi ini akan mengeluarkan peringatan penghentian di componentWillMount dan componentWillReceiveProps.
ian
1
@ian benar, perbaiki itu
Tomasz Mularczyk
5

Jika Anda menggunakan redux dan redux-thunk, solusi terbaik adalah menggunakan react-router-redux

// then, in redux actions for example
import { push } from 'react-router-redux'

dispatch(push('/some/path'))

Penting untuk melihat dokumen untuk melakukan beberapa konfigurasi.

Arnold Gandarillas
sumber
1
Saya datang ke sini berharap menemukan solusi yang tepat ini, terima kasih
vapurrmaid
4

Mendasarkan pada jawaban ini jika Anda memerlukan objek sejarah hanya untuk menavigasi ke komponen lain:

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>
  );
}
Konrad Grzyb
sumber
SALAH, Anda berada di dalam sebuah komponen. lihat // some-other-file.js dari jawaban yang diterima
storm_buster
0

Di 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} />}
        /> ...

Kemudian di komponen anak:

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

Dalam kasus khusus react-router, menggunakan contextadalah skenario kasus yang valid, misalnya

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

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

Anda dapat mengakses sebuah instance dari sejarah melalui konteks router, mis this.context.router.history.

Gajus
sumber
Pertanyaan secara khusus adalah menanyakan tentang kapan di luar komponen jadi this.context tidak tersedia sebagai opsi:> "Saya tahu bahwa saya dapat menggunakan, hoc withRouter, konteks reaksi, atau alat peraga perute acara ketika Anda berada dalam Komponen. Tetapi tidak demikian halnya bagi saya. "
SunshinyDoyle