React-router v4'te geçmişe nasıl ulaşılır?


106

React-Router v3'ten v4'e geçişte küçük bir sorun yaşıyorum. v3'te bunu her yerde yapabildim:

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

Bunu v4.0'da nasıl başarabilirim?

withRouterBir Bileşenin içindeyken hoc , react bağlamı veya olay yönlendirici sahne öğelerini kullanabileceğimi biliyorum. ama benim için durum böyle değil.

NavigatingOutsideOfComponents'ın v4'te eşdeğerliğini arıyorum


1
Teşekkürler @Chris, ama dediğim gibi, Bileşen içinde değilim.
storm_buster

@Chris bir yardımcı program sınıfında, lütfen github.com/ReactTraining/react-router/blob/master/docs/guides/… adresini kontrol edin , bu bir redux orta
savaşı


BrowserRouter'ı kök bileşen olarak kullandım. Bu şekilde App bileşenini Router ile kullanabilirim. Tam olarak istediğin gibi değil ama aynı gereksinimlerim var ve bu benim için yeterli.
Fool

Yanıtlar:


184

Sadece bir historynesneyi dışa aktaran bir modüle ihtiyacınız var . Sonra bu nesneyi projeniz boyunca içe aktarırsınız.

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

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

Ardından, yerleşik yönlendiricilerden birini kullanmak yerine <Router>bileşeni kullanırsınız .

// 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
Çok teşekkürler! Şu anda, react-router4 kullanarak, bunun yerine bu içe aktarmayı history.js'de kullanmak zorunda kaldım: createBrowserHistory'yi 'history / createBrowserHistory'den içe aktarın;
peter.bartos

3
Route'a history = {history}
ekleyip

1
ayrı bir dosya oluşturmak yerine withHistory'yi kullanabilir ve sahne alanında geçmişi alabiliriz. bu çözüm redux ile benim için işe yaramadı.
Zeel Shah

4
İçe createHashHistoryEğer kullanıyormuş HashRouter.
David Harkness

2
@HassanAzzam Muhtemelen react-router V5 kullanıyorsunuz ve bu cevap V5 için değil, V4 için çalışıyor. Şu anda aynı zorluğa sahibim ve her yere bakıyorum ama işe yarayamıyorum. history.push bileşen dışında çalışır, ancak Bağlantıya tıklamalar artık çalışmaz.
Waterlink

73

Bu çalışıyor! 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
bir bileşende olduğunuz sürece. Ben bir bileşende değilim
storm_buster

1
Teşekkür ederiz, bu, bir bileşenden başka bir rotaya bağlanmanın en kolay ve en basit yoludur. this.props.history.push('/some_route');Çalışması için yapmanız gerektiğini eklemeliyim .
dannytenaglias

1
@storm_buster const Component = props => {... // stuff}ve export default withRouter(Component)benim için durumsuz bir bileşen üzerinde çalışıyor
Karl Taylor

11

Kabul edilen cevaba Similiary ne yapabileceğini kullanımıdır reactve react-routerkendisi sağlamak için historyhangi nesneden sonra bir dosyada kapsamı ve ihracat yapabilirsiniz.

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

Daha sonra Bileşeni içe aktarır ve geçmiş değişkenini başlatmak için bağlarsınız:

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

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

Ve daha sonra uygulamanıza eklendiğinde içe aktarabilirsiniz:

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

Hatta bunu yapan npm paketi bile yaptım .


Reactjs 16.9'dan itibaren, bu çözüm componentWillMount ve componentWillReceiveProps üzerinde bir kullanımdan kaldırma uyarısı verecektir.
ian

1
@ian true, düzeltildi
Tomasz Mularczyk

5

Redux ve redux-thunk kullanıyorsanız en iyi çözüm react-router-redux kullanmak olacaktır.

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

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

Bazı konfigürasyonları yapmak için dokümanlara bakmak önemlidir.


1
Buraya bu kesin çözümü bulmayı umarak geldim, teşekkür ederim
vapurrmaid

5

Yalnızca diğer bileşene gitmek için geçmiş nesnesine ihtiyacınız varsa , bu yanıta dayanarak :

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

YANLIŞ, bir bileşenin içindesiniz. kabul edilen cevaptan // some-other-file.js'ye bakın
storm_buster

0

App.js'de

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

Sonra bir alt bileşende:

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

-2

Spesifik durumda react-router, kullanmak contextgeçerli bir durum senaryosudur, örn.

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

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

Geçmişin bir örneğine yönlendirici bağlamı aracılığıyla erişebilirsiniz, örn this.context.router.history.


Soru özellikle bir bileşenin dışında ne zaman olduğunu soruyor, bu yüzden this.context bir seçenek olarak mevcut değil:> "Bir Bileşenin içindeyken, Router ile hoc, tepki bağlamı veya olay yönlendirici sahne öğelerini kullanabileceğimi biliyorum. Ama benim için durum böyle değil. "
SunshinyDoyle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.