wake-up-neo.net

React-Router: Wie kann man Link manuell aufrufen?

Ich bin neu bei ReactJS und bei React-Router. Ich habe eine Komponente, die über Requisiten ein <Link/>-Objekt von React-Router empfängt. Wenn der Benutzer innerhalb dieser Komponente auf eine Schaltfläche "Weiter" klickt, möchte ich das <Link/>-Objekt manuell aufrufen.

Im Moment verwende ich refs, um auf die Hintergrundinstanz zuzugreifen und manuell auf das 'a' -Tag zu klicken, das <Link/> generiert. 

Frage: Gibt es eine Möglichkeit, den Link manuell aufzurufen (z. B. this.props.next.go)?

Dies ist der aktuelle Code, den ich habe:

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

Dies ist der Code, den ich gerne hätte:

//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>
         ...
      );
   }
});
...
79
Alan Souza

React Router v4 - Redirect-Komponente (aktualisiert 2017.04.15)

Die empfohlene Methode für v4 besteht darin, der Rendermethode eine Weiterleitung zuzulassen. Verwenden Sie State oder Requisiten, um zu bestimmen, ob die Weiterleitungskomponente angezeigt werden muss (was dann eine Weiterleitung auslöst).

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

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

React Router v4 - Referenz-Router-Kontext

Sie können auch den Kontext von Router nutzen, der der React-Komponente ausgesetzt ist.

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

So funktioniert <Redirect /> unter der Haube.

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

Reagieren Sie Router v4 - Historisch externes Objekt

Wenn Sie dennoch etwas Ähnliches wie bei der Implementierung von v2 tun müssen, können Sie eine Kopie von BrowserRouter erstellen und dann die history als exportierbare Konstante verfügbar machen. Im Folgenden finden Sie ein einfaches Beispiel. Sie können es aber auch zusammenstellen, um bei Bedarf anpassbare Requisiten zu injizieren. Es gibt einige Einschränkungen mit Lebenszyklen, aber es sollte immer den Router neu rendern, genau wie in v2. Dies kann für Umleitungen nach einer API-Anforderung von einer Aktionsfunktion hilfreich sein.

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

Letzte BrowserRouter, die erweitert werden soll: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

Reagieren Sie Router v2

Schieben Sie einen neuen Status in die browserHistory-Instanz:

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

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

147
Matt Lo

React Router 4 enthält ein withRouterHOC , mit dem Sie über this.props auf das Objekt history zugreifen können:

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)
62
aw04

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

oder Sie können sogar onClick ausführen (gewalttätigere Lösung):

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

Router reagieren 4

Sie können die Push-Methode einfach über den Kontext in Version 4 aufrufen:

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

wo Kontext ist:

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

Ok, ich glaube, ich konnte eine passende Lösung dafür finden.

Anstatt <Link/> als prop to Document zu senden, sende ich <NextLink/>, einen benutzerdefinierten Wrapper für den Reakt-Router-Link. Auf diese Weise kann ich den rechten Pfeil als Teil der Link-Struktur verwenden, ohne dass Routing-Code im Document-Objekt angezeigt wird.

Der aktualisierte Code sieht wie folgt aus:

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

P.S : Wenn Sie die neueste Version des Reakt-Routers verwenden, müssen Sie möglicherweise this.context.router.transitionTo anstelle von this.context.transitionTo verwenden. Dieser Code funktioniert gut mit der Version 0.12.X von Reakt-Router.

2
Alan Souza

das ist wieder JS :) das funktioniert immer noch ....

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

<Link id="something" to={/somewhaere}> the link </Link>
0
Taggart Jensen