React-router: Link'i manuel olarak nasıl çağırabilirim?


131

ReactJS ve React-Router'da yeniyim. React-yönlendiriciden bir <Link/>nesneyi destekleyen bir bileşenim var . Kullanıcı bu bileşenin içindeki bir 'sonraki' düğmesine her tıkladığında, nesneyi manuel olarak çağırmak istiyorum .<Link/>

Şu anda, destekleme örneğine erişmek için refs kullanıyorum ve oluşturan 'a' etiketine elle tıklıyorum .<Link/>

Soru: Bağlantıyı manuel olarak çalıştırmanın bir yolu var mı (örneğin this.props.next.go)?

Şu an sahip olduğum kod bu:

//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />

//in Document.js
...
var Document = React.createClass({
   _onClickNext: function() {
      var next = this.refs.next.getDOMNode();
      next.querySelectorAll('a').item(0).click(); //this sounds like hack to me
   },
   render: function() {
      return (
         ...
         <div ref="next">{this.props.next} <img src="rightArrow.png" onClick={this._onClickNext}/></div>
         ...
      );
   }
});
...

Bu sahip olmak istediğim kod:

//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />

//in Document.js
...
var Document = React.createClass({
   render: function() {
      return (
         ...
         <div onClick={this.props.next.go}>{this.props.next.label} <img src="rightArrow.png" /> </div>
         ...
      );
   }
});
...

Yanıtlar:


199

React Router v4 - Yönlendirme Bileşeni (güncelleme 2017/04/15)

V4'ün önerdiği yol, oluşturma yönteminizin bir yönlendirmeyi yakalamasına izin vermektir. Yönlendirme bileşeninin gösterilmesi gerekip gerekmediğini belirlemek için durum veya props kullanın (daha sonra tetikleyici bir yönlendirmedir).

import { Redirect } from 'react-router';

// ... your class implementation

handleOnClick = () => {
  // some action...
  // then redirect
  this.setState({redirect: true});
}

render() {
  if (this.state.redirect) {
    return <Redirect push to="/sample" />;
  }

  return <button onClick={this.handleOnClick} type="button">Button</button>;
}

Referans: https://reacttraining.com/react-router/web/api/Redirect

React Router v4 - Referans Yönlendirici Bağlamı

RouterReact bileşeninin maruz kaldığı bağlamından da yararlanabilirsiniz .

static contextTypes = {
  router: PropTypes.shape({
    history: PropTypes.shape({
      push: PropTypes.func.isRequired,
      replace: PropTypes.func.isRequired
    }).isRequired,
    staticContext: PropTypes.object
  }).isRequired
};

handleOnClick = () => {
  this.context.router.push('/sample');
}

<Redirect />Kaputun altında böyle çalışır.

Referans: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js#L46,L60

React Router v4 - Geçmiş Nesnesini Harici Olarak Değiştir

Yine de v2 uygulamasına benzer bir şey yapmanız gerekiyorsa, bir kopyasını oluşturabilir ve BrowserRouterardından historydışa aktarılabilir sabit olarak gösterebilirsiniz . Aşağıda temel bir örnek verilmiştir, ancak gerekirse özelleştirilebilir sahne ile enjekte etmek için oluşturabilirsiniz. Yaşam döngüleriyle ilgili bazı uyarılar vardır, ancak Yönlendiriciyi v2'de olduğu gibi her zaman yeniden göndermelidir. Bu, bir eylem işlevinden gelen bir API isteğinden sonra yeniden yönlendirmeler için yararlı olabilir.

// browser router file...
import createHistory from 'history/createBrowserHistory';
import { Router } from 'react-router';

export const history = createHistory();

export default class BrowserRouter extends Component {
  render() {
    return <Router history={history} children={this.props.children} />
  }
}

// your main file...
import BrowserRouter from './relative/path/to/BrowserRouter';
import { render } from 'react-dom';

render(
  <BrowserRouter>
    <App/>
  </BrowserRouter>
);

// some file... where you don't have React instance references
import { history } from './relative/path/to/BrowserRouter';

history.push('/sample');

En son BrowserRoutergenişletilecek: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

React Router v2

browserHistoryÖrneğe yeni bir durum aktarın:

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

Referans: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md


7
hashHistory.push ( '/ numune'); browserHistory yerine hashHistory kullanıyorsanız
sanath_p

1
bu özellikle material-ui kitaplığında kullanışlıdır, çünkü containerElement = {<Link to = "/" />} her zaman bağlantıyı
çağırmaz

2
Yeniden yönlendirme seçeneğinde, push (yani, <Yönlendirme push />) belirtmeniz gerektiğini unutmayın. Varsayılan olarak, bir Bağlantıyı manuel olarak çağırmakla aynı olmayan bir değişiklik
yapacaktır


1
Yönlendirme benim için çalışmıyor, ancak withRouter ile aw04 çözümü daha basit ve çalışıyor
stackdave

90

React Router 4, aşağıdakiler aracılığıyla nesneye erişmenizi sağlayan bir withRouter HOC içerir :historythis.props

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

class Foo extends Component {
  constructor(props) {
    super(props)

    this.goHome = this.goHome.bind(this)
  }

  goHome() {
    this.props.history.push('/')
  }

  render() {
    <div className="foo">
      <button onClick={this.goHome} />
    </div>
  }
}

export default withRouter(Foo)

9
Bu benim için çalıştı ve en basit çözüm gibi görünüyor.
Rubycut

5
En iyi çözüm budur. Neden bu kadar az oy aldığını anlamıyorum.
Benoit

1
evet, bağlantıya birkaç kez tıklayabilirsiniz ve tarayıcı geri çalışmaz. gerçekten geri dönmek için tarayıcıyı birkaç kez tekrar tıklamanız gerekecek
Vladyslav Tereshyn

@VladyslavTereshyn bazı koşullu mantık ekleyebilirsiniz: if ((this.props.location.pathname + this.props.location.search)! == navigateToPath) {...}
MattWeiler

15

In versiyon 5.x , kullanabilirsiniz useHistorykancasını react-router-dom:

// Sample extracted from https://reacttraining.com/react-router/core/api/Hooks/usehistory
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>
  );
}

En iyi çözüm budur. Koşullu bir mantık eklerseniz, bir kullanıcı aynı düğmeyi birden çok kez tıkladığında geçmişte yinelenen girişlerden kaçınabilirsiniz:if ((routerHistory.location.pathname + routerHistory.location.search) !== navigateToPath) { routerHistory.push(navigateToPath); }
MattWeiler

historyDeğişken bildirmem gerekiyordu , dizin useHistory().push
çağırmaya

bu, en modern tepkisel çözüm gibi görünüyor.
Youngjae

8

https://github.com/rackt/react-router/blob/bf89168acb30b6dc9b0244360bcbac5081cf6b38/examples/transitions/app.js#L50

veya onClick bunu çalıştırmayı bile deneyebilirsiniz (daha şiddetli çözüm):

window.location.assign("/sample");

Kod satırları değiştikçe, detayları kopyalayıp cevabınızı burada açıklarsanız cevabınız daha iyi olacaktır. Ayrıca assignbir özellik değil, bir fonksiyondur.
WiredPrairie

(Ama yine de bir dosyanın belirli bir satırına bir bağlantınız var). Lütfen yanıtınıza belirli bir öneriyi ekleyin, yalnızca bir bağlantıyı değil.
WiredPrairie

Cevabınız için teşekkürler @grechut. Ancak, Belgenin yönlendirici hakkında hiçbir şey bilmediğinden emin olmak istiyorum. Beklediğim davranış şudur: 'Kullanıcı sağ oku tıklarsa, sonraki işlevi çağırın'. Sonraki işlev bir bağlantı olabilir veya olmayabilir.
Alan Souza

React'in (FB ve Google yönlendirmelerinin olduğu giriş ekranları) dışında ele alınan birkaç sayfam var, bu nedenle bu sayfalar için gezinmede "browserHistory.push ('/ home')" dan beri buna ihtiyacım vardı; yalnızca URL'yi değiştirdi, sayfaları yönlendiremedi. Teşekkür ederim.
Deborah

7
Bu, react yönlendiricili bir uygulama için istenen bir davranış değil, @grechut sayfasını yeniden yükleyecektir.
Abhas

2

Tamam, sanırım bunun için uygun bir çözüm bulabildim.

Şimdi, Belgeye prop<Link/> olarak göndermek yerine , react-yönlendirici Link için özel bir sarmalayıcı olan gönderiyorum . Bunu yaparak, yine de Belge nesnesi içinde yönlendirme koduna sahip olmaktan kaçınırken, Bağlantı yapısının bir parçası olarak sağ oka sahip olabiliyorum.<NextLink/>

Güncellenen kod aşağıdaki gibi görünür:

//in NextLink.js
var React = require('react');
var Right = require('./Right');

var NextLink = React.createClass({
    propTypes: {
        link: React.PropTypes.node.isRequired
    },

    contextTypes: {
        transitionTo: React.PropTypes.func.isRequired
    },

    _onClickRight: function() {
        this.context.transitionTo(this.props.link.props.to);
    },

    render: function() {
        return (
            <div>
                {this.props.link}
                <Right onClick={this._onClickRight} />
            </div>  
        );
    }
});

module.exports = NextLink;

...
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
var nextLink = <NextLink link={sampleLink} />
<Document next={nextLink} />

//in Document.js
...
var Document = React.createClass({
   render: function() {
      return (
         ...
         <div>{this.props.next}</div>
         ...
      );
   }
});
...

Not : React-router'ın en son sürümünü kullanıyorsanız, this.context.router.transitionTobunun yerine kullanmanız gerekebilir this.context.transitionTo. Bu kod, react-yönlendirici 0.12.X sürümü için düzgün çalışacaktır.


2

React Yönlendirici 4

Push yöntemini v4'teki bağlam aracılığıyla kolayca çağırabilirsiniz:

this.context.router.push(this.props.exitPath);

bağlam nerede:

static contextTypes = {
    router: React.PropTypes.object,
};

Kullanıldığında BrowserRouter, bileşenlerimin bağlam nesnesi bir routernesne içermiyor . Yanlış bir şey mi yapıyorum?
pilau

Bağlamı bileşende mi ayarlıyorsunuz (yukarıdaki ikinci blok)?
Chris

Geldiğiniz için teşekkürler! Sonunda bu benim için çalıştı: router: React.PropTypes.object.isRequired. isRequiredAnahtar olmadan neden işe yaramadığını bilmiyorum . Ayrıca, bağlamı <Link>elde edebiliyor gibi görünüyor history, ancak onu kopyalayamadım.
pilau

İlginç olanı - eğer bir codepen koyarsanız, hala takılı kalırsanız, hata ayıklamanıza yardımcı olabilirim
Chris

this.props.history.push()React Router v4'te kullanabileceğiniz gibi görünüyor . Bunu yalnızca React Router'ın geçtiği aksesuarları inceleyerek buldum. İşe yarıyor gibi görünüyor ama bunun iyi bir fikir olup olmadığından emin değilim.
sean_j_roberts

-1

yine bu JS :) bu hala çalışıyor ....

var linkToClick = document.getElementById('something');
linkToClick.click();

<Link id="something" to={/somewhaere}> the link </Link>
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.