Je suis nouveau sur ReactJS et React-Router. J'ai un composant qui reçoit, via les accessoires, un objet <Link/>
de react-router. Chaque fois que l'utilisateur clique sur un bouton "Suivant" dans ce composant, je souhaite appeler l'objet <Link/>
manuellement.
En ce moment, j'utilise refs pour accéder à instance de sauvegarde et je clique manuellement sur la balise 'a' générée par <Link/>
.
Question: Existe-t-il un moyen d'invoquer manuellement le lien (par exemple this.props.next.go
)?
C'est le code actuel que j'ai:
//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>
...
);
}
});
...
C'est le code que j'aimerais avoir:
//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>
...
);
}
});
...
La méthode recommandée par la v4 consiste à autoriser votre méthode de rendu à intercepter une redirection. Utilisez state ou props pour déterminer si le composant de redirection doit être affiché (ce qui déclenche alors une redirection).
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>;
}
Référence: https://reacttraining.com/react-router/web/api/Redirect
Vous pouvez également tirer parti du contexte de Router
exposé au composant React.
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');
}
Voici comment <Redirect />
fonctionne sous le capot.
Si vous avez encore besoin de faire quelque chose de similaire à l'implémentation de la version 2, vous pouvez créer une copie de BrowserRouter
, puis exposer history
en tant que constante exportable. Vous trouverez ci-dessous un exemple élémentaire, mais vous pouvez le composer pour l’injecter des accessoires personnalisables si nécessaire. Il existe des mises en garde concernant les cycles de vie, mais il convient de toujours rendre le routeur, tout comme dans la v2. Cela peut être utile pour les redirections après une demande d'API à partir d'une fonction d'action.
// 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');
Dernière BrowserRouter
à prolonger: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
Poussez un nouvel état dans l'instance browserHistory
:
import {browserHistory} from 'react-router';
// ...
browserHistory.Push('/sample');
Référence: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
React Router 4 comprend un withRouterHOC qui vous donne accès à l’objet history
via this.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)
ou vous pouvez même essayer d’exécuter onClick (solution plus violente):
window.location.assign("/sample");
Ok, je pense que j'ai été capable de trouver une solution adéquate pour cela.
Maintenant, au lieu d’envoyer <Link/>
en tant que prop à Document, j’envoie <NextLink/>
qui est un wrapper personnalisé pour le lien react-router. En faisant cela, je peux avoir la flèche vers la droite dans la structure de lien tout en évitant d’avoir un code de routage dans l’objet Document.
Le code mis à jour se présente comme suit:
//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 : Si vous utilisez la dernière version de react-router, vous devrez peut-être utiliser this.context.router.transitionTo
au lieu de this.context.transitionTo
. Ce code fonctionnera correctement pour react-router version 0.12.X.
encore une fois c'est JS :) cela fonctionne toujours ....
var linkToClick = document.getElementById('something');
linkToClick.click();
<Link id="something" to={/somewhaere}> the link </Link>