Reaksiyon yönlendirici V4'ü kullanarak programlı olarak gezinin


336

Az react-routerönce v3'ten v4'e geçtim .
Ancak a Component. Üye işlevinde programlı olarak gezinmek nasıl emin değilim . yani handleClick()işlevde /path/some/wherebazı verileri işledikten sonra gitmek istiyorum . Bunu şu şekilde yapardım:

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

Ama v4'te böyle arayüzler bulamıyorum.
V4'ü kullanarak nasıl gezinebilirim?


3

6
Ya bir yerden farklı bir yerden erişmek istiyorsanız Component? Örneğin, redux eylemlerinin içinde.
Maximus S

73
bazen neden sadece bir bağlantıdan diğerine geçmek için bu kadar karmaşık olduğunu merak ediyorum =))
Thai Tran

12
Bu gün ve yaş yönlendirmesinin bu kadar karmaşık olmayacağı düşünülebilir.
JohnAllen

Yanıtlar:


414

Tarayıcı ortamlarını hedefliyorsanız react-router-dom, yerine paket kullanmanız gerekir react-router. Çekirdek, ( react) ve platforma özgü kodu ( react-dom, react-native) iki ayrı paket kurmanıza gerek olmayan ince farkla ayırmak için React ile aynı yaklaşımı izliyorlar , böylece ortam paketleri her şeyi içeriyor ihtiyacınız var. Projenize şu şekilde ekleyebilirsiniz:

yarn add react-router-dom

veya

npm i react-router-dom

Yapmanız gereken ilk şey <BrowserRouter>, uygulamanızdaki en üst ana bileşen olarak a sağlamaktır . <BrowserRouter>HTML5 historyAPI'sını kullanır ve sizin için yönetir, böylece onu kendiniz örnekleme ve <BrowserRouter>bir prop olarak bileşene aktarma konusunda endişelenmenize gerek yoktur (önceki sürümlerde yapmanız gerektiği gibi).

V4'te, programlı olarak gezinmek için , uygulamanızdaki en üst üst öğe olarak bir sağlayıcı bileşeniniz olduğu sürece historyReact aracılığıyla kullanılabilen nesneye erişmeniz gerekir . Kütüphane , bir özellik olarak içerdiği nesneyi bağlam yoluyla ortaya koyar . Arayüz gibi çeşitli navigasyon yöntemleri sunmaktadır , ve diğerleri arasında,. Sen özellikleri ve yöntemlerin tüm listesini kontrol edebilirsiniz burada .context<BrowserRouter> routerhistoryhistorypushreplacegoBack

Redux / Mobx kullanıcıları için Önemli Not

Uygulamanızda durum yönetimi kitaplığınız olarak redux veya mobx kullanıyorsanız, konum farkında olması gereken, ancak bir URL güncellemesini tetikledikten sonra yeniden oluşturulmayan bileşenlerle ilgili sorunlarla karşılaşmış olabilirsiniz

Bu oluyor çünkü bağlam modelini kullanan bileşenlere react-routergeçiyor location.

Connect ve gözlemci, shouldComponentUpdate yöntemleri mevcut sahne ve sonraki sahne özellikleri arasında sığ bir karşılaştırma yapan bileşenler oluşturur. Bu bileşenler yalnızca en az bir pervane değiştiğinde yeniden oluşturulur. Bu, konum değiştiğinde güncelleme yapmalarını sağlamak için, konum değiştiğinde değişen bir destek vermeleri gerektiği anlamına gelir.

Bunu çözmek için 2 yaklaşım:

  • Bağlı bileşeninizi yolsuz bir şekilde sarın <Route />. Geçerli locationnesne, <Route>oluşturduğu bileşene bir geçişin sağladığı desteklerden biridir
  • Bağlı bileşeninizi withRouter, aslında locationbir pervane ile aynı etkiye sahip ve enjekte eden yüksek dereceli bileşenle sarın

Bunu bir kenara bırakarak, tavsiyeyle sipariş edilen programlı olarak gezinmenin dört yolu vardır:

1. Bir <Route>Bileşenin Kullanılması

Bildirici bir tarzı teşvik eder. Sürüm 4'ten önce, <Route />bileşenler rota yapınızı önceden düşünmek zorunda olan bileşen hiyerarşinizin en üstüne yerleştirildi. Bununla birlikte, artık URL'nize bağlı olarak koşullu oluşturma için daha iyi bir kontrole sahip olmanızı sağlayan, ağacınızın herhangi bir yerinde<Route> bileşenlere sahip olabilirsiniz . enjekte eder , ve bileşeniniz sahne olarak. Navigasyon yöntemleri (örneğin , , ...) özellikleri olarak mevcuttur nesne.RoutematchlocationhistorypushreplacegoBackhistory

Bir ile bir şeyler işlemek için 3 yol vardır Routeya kullanılarak, component, renderveya childrensahne, ama aynı onlardan birden fazla kullanmayın Route. Seçim, kullanım durumuna bağlıdır, ancak temel olarak ilk iki seçenek yalnızca pathurl konumuyla eşleşirse childrenbileşeninizi oluşturur ; oysa bileşenle birlikte yolun konumla eşleşip eşleşmediği görüntülenir (URL'ye göre kullanıcı arayüzünü ayarlamak için yararlıdır) eşleştirme).

Eğer bileşen render çıktı özelleştirmek istiyorsanız , bir fonksiyonun içinde bileşeni sarmak gerekiyor ve kullanmak rendersizin bileşene sen dışında, arzu başka sahne geçmek için, seçeneğini match, locationve history. Açıklamak için bir örnek:

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

2.- withRouterHoC Kullanımı

Bu yüksek dereceli bileşen, aynı sahne donanımını enjekte edecektir Route. Bununla birlikte, dosya başına yalnızca 1 HoC'ye sahip olabileceğiniz sınırlama boyunca devam eder.

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

3. - Bir Redirectbileşen kullanmak

Bir oluşturma <Redirect>yeni bir konuma gider. Ancak, varsayılan olarak , geçerli konumun, sunucu tarafı yönlendirmeleri (HTTP 3xx) gibi yenisiyle değiştirildiğini unutmayın. Yeni konum, tobir dize (yönlendirilecek URL) veya bir locationnesne olabilecek prop tarafından sağlanır . Bunun yerine geçmişe yeni bir giriş eklemek istiyorsanız , bir pushpervane de geçirin vetrue

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

4.- routerBağlam aracılığıyla manuel erişim

Biraz cesaret kırıldı çünkü bağlam hala deneysel bir API ve gelecekteki React sürümlerinde kırılması / değişmesi muhtemel

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

Söylemeye gerek yok, tarayıcı dışı ekosistemler için olması gereken, örneğin bellekte<NativeRouter> bir gezinme yığınını çoğaltan ve paket yoluyla kullanılabilen React Native platformunu hedefleyen başka Yönlendirici bileşenleri de var .react-router-native

Daha fazla referans için resmi belgelere göz atmakta tereddüt etmeyin . Ayrıca, reaksiyon yönlendiricisinin v4'e oldukça güzel bir giriş sağlayan ve bazı önemli değişiklikleri vurgulayan kütüphanenin ortak yazarlarından biri tarafından yapılan bir video da var .


2
V4 kullanıyorum ve yukarıdaki iyi çalışıyor. Bazı garip seçenekler gibi görünüyor ama yukarıdaki kesinlikle çalışır gibi V4 yönlendirici ile mucking hakkında biraz zaman geçirdim. Sana ithal ediyoruz varsayalım withRouterdenreact-router-dom
Sam Parmenter

3
Ben ithal ediyorum withRouterdan react-router-dom. History.push URL'yi değiştirir, ancak <Route>sayfayı yenilemeyi zorlayana kadar
yüklenmiyor

1
@rauliyohmc Bu konuda yanılmışım. Sorun şu ki <Router> , dekore edilmiş bir React bileşeninin içinde bu sorunu@observer tetikleyen var . Etrafında bu tür her React bileşeni üzerinde çalışmaktır . @withRouter
BreakDS

3
Bu harika cevaba rastlayanlar için withRouter, sadece Routebaşlık altında bir HOC var . Bu, yalnızca 3 sahne, geçmiş, maç ve konum kullandığı anlamına gelir . Yukarıdaki örnekte , eklenecek pushbir prop olduğu anlaşılıyor , ancak durum böyle değil. bunun yerine kullanılması gerekir. Umarım bu biraz karışık olan başkalarına yardımcı olur. withRouterButtonToNavigateprops.history.push
vinnymac

39
Vay. browserHistory.push('/path/some/where')çok daha basit görünüyor. Yazarlar zorunlu programlamayı caydırmaya çalışıyor, ancak bazen daha iyi çalışıyor!
lux

149

Bunu yapmanın en kolay yolu:

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

Not:

  • Kullanılamazsa history prop, üst bileşenden eylemi çağırmak istediğiniz bileşene iletmek isteyebilirsiniz.

10
4.0 yönlendirici kullanıyorum, ama sahne üzerinde geçmiş anahtarı yok. Nasıl düzeltebilirim?
Nicolas S.Xu

41
Eğer yoksa this.props.historysizin bileşende mevcut sonra olabildiğince import {withRouter} from 'react-router-dom'sonra export default withRouter(MyComponent)(veya const MyComponent = withRouter(...)) ve ekler historysizin bileşenin sahne öğeyi.
Malvineous

@Malvineous thats ilginç, bunu bilmiyordum! Deneyeceğim!
Jikku Jose

2
Temel bir şeyi kaçırmam gerekiyor, çünkü bu benim için harika çalışıyor, bu yüzden tüm cevapların neden bu kadar uzun açıklamalar gerektirdiğine dair hiçbir fikrim yok.
Joshua Pinter

bileşen yeniden yüklemesini nasıl önleyebilir history.pushve tıkladığımızda olduğu gibi güncellemeyi nasıl tetikleyebiliriz<Link>
Rahul Yadav

55

React-Router v4'e geçerken benzer bir sorun yaşadım, bu yüzden aşağıda çözümümü açıklamaya çalışacağım.

Lütfen bu cevabı sorunu çözmenin doğru yolu olarak düşünmeyin, React Router v4 daha olgunlaştıkça ve betadan ayrıldıkça daha iyi bir şeyin ortaya çıkması için iyi bir şans olduğunu hayal ediyorum. .

Bağlam için, zaman zaman Redux-Sagageçmiş nesnesini programsal olarak değiştirmek için kullandığım için bu sorunu yaşadım (bir kullanıcı başarıyla kimlik doğrulaması yaptığında söyle).

React Router belgelerinde, <Router> bileşene bir bakın ve kendi geçmiş nesnenizi bir prop üzerinden geçirme yeteneğiniz olduğunu görebilirsiniz. Bu çözümün özüdür - biz geçmişi nesnesi tedarik etmek React-Routerbir gelen küresel modülü.

Adımlar:

  1. Geçmiş npm modülünü takın - yarn add history veya npm install history --save
  2. adlı bir dosya oluşturmak history.jsiçin de App.jsdüzey klasörde (bu benim tercihi oldu)

    // src/history.js
    
    import createHistory from 'history/createBrowserHistory';
    export default createHistory();`
  3. Bu geçmiş nesnesini Yönlendirici bileşeninize şu şekilde ekleyin:

    // src/App.js
    
    import history from '../your/path/to/history.js;'
    <Router history={history}>
    // Route tags here
    </Router>
  4. Sadece ithal ederek önceki gibi URL'yi ayarlayın senin küresel geçmişi nesnesi:

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

Her şey şimdi senkronize halde kalmalı ve ayrıca bir bileşen / kapsayıcı aracılığıyla değil, geçmiş nesnesini programlı olarak ayarlama yoluna erişebilirsiniz.


5
Bu değişiklik benim için çalıştı, ama sadece bir bileşenin dışına çıktığım için. OP gibi bir bileşenin içinde geziniyor olsaydım, Routebileşen tarafından aktarılan destekleri kullanarak @ rauliyohmc tarafından önerilen yaklaşımı kullanırdım .
Dan Ellis

2
08 / 17'den itibaren önerilen yaklaşım budur
Spets

2
@Spets Benim durumumda, bu tür bir yaklaşım kullanırsam, bağlantı itme sonra düzgün güncellenir, ancak bileşenler düzgün işlenmez (örneğin, bağlantıyı güncelledikten sonra, sayfa yenilemeyi zorlamadığınız sürece bileşen güncellenmez). Bunun önerilen yaklaşım olduğunu nereden buldunuz? Herhangi bir bağlantı / kaynak var mı?
serin

2
@ScottCoates Yukarıdaki örneği kullanarak, aslında geçmişi bir parametre olarak sağlayarak, ancak düğüm modüllerinde kendim hata ayıklama yaptıktan sonra sıraladım. Bunun yerine, reaktif yönlendirici-dom'un en son sürümünde kendi başına Router adı verilen başka bir nesne olduğunda "Yönlendirici olarak BrowserHistory" içe aktarma kullanılarak web genelinde yaygın olarak yapılan bir hata vardır. Bunu yukarıdaki örnekte oluşturulan tarihle birlikte kullanmak gayet iyi çalışıyor.
serin

2
url güncellenir, ancak sayfa yeni köke göre işlenmez. Herhangi bir çözüm? Tetikleme rotası neden bu kadar zor? Tepki tasarlayan insanlar aklından mı çıkıyor?
Nicolas S.Xu

43

TL; DR:

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

Basit ve bildirime cevap kullanmak gerektiğidir <Redirect to={URL} push={boolean} />birliktesetState()

push: boolean - true olduğunda, yeniden yönlendirme geçerli girişi değiştirmek yerine tarihe yeni bir giriş gönderir.


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

Tam örnek burada . Daha fazlasını buradan okuyun .

PS. Örnek, durumu başlatmak için ES7 + Özellik Başlatıcıları kullanır . Eğer ilgileniyorsanız, buraya da bakın .


5
Bu cevap kabul edilmelidir. En basit zarif çözüm! @Lustoykov için +1 +1
Ali Abbas Jaffri

1
Düğmem bir başlıkta olduğundan ve yalnızca bir kez gezineceğinden, componentDidUpdate öğesinde false değerine geri gitmeyi de ayarladım.
peterorum

Bu yalnızca sayfa yüklendiğinde yönlendirme hakkında bilgi sahibi olduğunuzda çalışır. Eşzamansız bir çağrının geri dönmesini bekliyorsanız (örneğin, Google ile kimlik doğrulaması veya başka bir şey), history.push()yöntemlerden birini kullanmanız gerekir .
brittohalloran

Gerçekten değil, yine de <Yönlendir /> bileşeniyle birlikte reaksiyonun bildirici doğasından faydalanabilirsiniz. Sayfa yüklenmezse, başka bir <Yönlendirme />
Lyubomir

@brittohalloran uygun reaksiyon yönlendirici kullanarak bu yöntemin fikri, yeniden oluşturma zorlamak için setState kullandığınızdan emin olmaktır.
Özel Birisi

16

useHistoryİşlev bileşenlerini kullanıyorsanız kanca kullanın

Örnek useHistoryalmak için kancayı kullanabilirsiniz history.

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

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

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

useHistoryKanca size gezinmek için kullanabileceğini tarih örneğine erişim sağlar.

Kullanım historymülkiyet içeride sayfası bileşenleri

React Router history, sayfa bileşenleri dahil olmak üzere bazı özellikler enjekte eder .

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

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

withRouterYönlendirici özelliklerini enjekte etmek için alt bileşenleri sarma

withRouterwrapper yönlendirici özelliklerini bileşenlere enjekte eder. Örneğin, bu sarmalayıcıyı, kullanıcı menüsünün içine yerleştirilmiş oturum kapatma düğmesi bileşenine yönlendirici enjekte etmek için kullanabilirsiniz.

import { withRouter } from "react-router";

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

export default LogoutButton;

11

Ayrıca geçmiş nesnesine erişmek için sahne aracını da kullanabilirsiniz: this.props.history.push('new_url')


5
Yalnızca bileşende doğrudan Yönlendiriciden indiğinde kullanışlıdır. Bu özelliği ihtiyacınız olan her bir bileşene tarih pervanesini
geçmemek için

3
Eğer yoksa this.props.historysizin bileşende mevcut sonra olabildiğince import {withRouter} from 'react-router-dom'sonra export default withRouter(MyComponent)(veya const MyComponent = withRouter(...)) ve ekler historysizin bileşenin sahne öğeyi.
Malvineous

9

1. Adım: İçe aktarılacak tek bir şey vardır:

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

2. Adım: Rotanızda geçmişi aktarın:

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

3.Adım: Tarih, bir sonraki Bileşendeki desteklerin bir parçası olarak kabul edilir, böylece şunları yapabilirsiniz:

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

Bu kolay ve gerçekten güçlüydü.


7

Bu çalışıyor:

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

Benim cevabım benzer Alex'in . React-Router'ın bunu neden bu kadar gereksiz hale getirdiğinden emin değilim. Temelde küresel olana erişmek için neden bileşenimi bir HoC ile sarmam gerekiyor?

Her neyse, nasıl uygulandıklarına bir bakarsanız, tarihin<BrowserRouter> etrafındaki küçük bir paket .

Herhangi bir yerden içe aktarabilmemiz için bu geçmişi biraz dışarı çekebiliriz. Ancak, hile, sunucu tarafı oluşturma yapıyorsanız importve geçmiş modülünü denerseniz , yalnızca tarayıcı API'ları kullandığından çalışmaz. Ancak sorun değil çünkü genellikle yalnızca bir tıklamaya veya başka bir istemci tarafı etkinliğine yanıt olarak yeniden yönlendiririz. Bu yüzden sahte yapmak sorun değil:

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

Webpack'in yardımıyla bazı değişkenleri tanımlayabiliriz, böylece hangi ortamda olduğumuzu biliriz:

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

Ve şimdi yapabilirsin

import history from './history';

Herhangi bir yerden. Sunucuda boş bir modül döndürür.

Bu sihirli değişkenleri kullanmak istemiyorsanız, sadece gerekli requireolan global nesnede (olay işleyicinizin içinde) yapmanız gerekir . importişe yaramaz çünkü yalnızca en üst düzeyde çalışır.


6
Kahretsin, çok karmaşık hale getirdiler.
Abhishek

4
Seninle tamamen aynı fikirdeydim. Bu sadece bir navigasyon için çok karmaşık
Thai Tran

5

Sanırım @rgommezz, çoğu durumda eksi bence oldukça önemli.

// 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");

Bu, bileşenlerim üzerinde çok fazla HoC yapmadan istediğim herhangi bir bileşenden gezinme yapmak için arayabileceğim eylemler / çağrılarla basit bir hizmet yazmamı sağlıyor ...

Bu çözümü daha önce kimsenin neden sağlamadığı açık değil. Umarım yardımcı olur ve bununla ilgili herhangi bir sorun görürseniz lütfen bana bildirin.


4

Birkaç gündür v4 test ediyorum ve .. Şimdiye kadar seviyorum! Bir süre sonra mantıklı geliyor.

Ben de aynı soru vardı ve aşağıdaki gibi en iyi çalıştı gibi idare buldum (ve hatta nasıl amaçlanmış olabilir). Devlet, üçlü bir operatör ve <Redirect>.

Yapıcıda ()

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

Render () içinde

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

Tıklama işleyicisinde ()

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

Umarım yardımcı olur. Bilmeme izin ver.


Bu yöntemle ilgili herhangi bir tuzak var mı? İle yaptığım projede sadece kurucuda durum belirlediğimde çalışır, oradan istediğim herhangi bir sayfaya yönlendirebilirim. Ama (sahne örneğin değişti) Ben yeni devletle denilen yöntem hale bakın, ama yönlendirme aynı sayfaya bakınız olmaz olayın üzerine devlet ayarladığınızda
Dmitry Malugin

Pitfall tarihin yerini alacak, bu yüzden geri vuramayacaksınız - yani temelde bu iyi bir çözüm değil.
dannytenaglias

4

Bir süre bununla mücadele ettim - çok basit, ama çok karmaşık bir şey, çünkü ReactJS web uygulamaları yazmanın tamamen farklı bir yolu olduğundan, bize daha yaşlı insanlar için çok yabancı!

Bu karışıklığı soyutlamak için ayrı bir bileşen oluşturdum:

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

Ardından render()yönteminize ekleyin :

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

Bu çözümü oldukça faydalı buluyorum. Kodu kopyalıyorum. Github'a koyduğunuzu bilmeme izin verin - doğrudan size atfedeceğim.
Abhinav Manchanda

3

Bu korkunç tasarımla başa çıkmanın başka bir yolu olmadığından, withRouter HOC yaklaşımını kullanan genel bir bileşen yazdım . Aşağıdaki örnek bir buttonöğeyi kaydırmaktır , ancak ihtiyacınız olan herhangi bir tıklanabilir öğeye değiştirebilirsiniz:

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

Kullanımı:

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

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

Bu.props.history öğesini bileşeninizde bulamadıysanız, bunu deneyin

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

Çok teşekkürler!
QauseenMZ

1

Bazen uygulamadan sonra düğmelere göre rota değiştirmeyi tercih ettiğim için, bu benim için işe yarayan minimal bir çalışma örneğidir:

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

Kullanarak bir yönlendiriciyi tamamen başlatmadan önce yeniden yönlendirmek isteyenler için React Routerveya React Router Domyalnızca geçmiş nesnesine erişerek ve yapınız içinde üzerine yeni bir durum göndererek bir yönlendirme sağlayabilirsiniz app.js. Aşağıdakileri göz önünde bulundur:

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


}

Burada, bir alt alana bağlı çıkış Rotalarını, bileşen oluşturulmadan önce geçmiş nesnesiyle etkileşime girerek değiştirmek istiyoruz, yine de rotalarımızı incelikte bırakırken etkili bir şekilde yönlendirebiliriz.

window.history.pushState('', '', './login');
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.