प्रतिक्रिया-राउटर: लिंक को मैन्युअल रूप से कैसे करें?


131

मैं ReactJS और React-Router के लिए नया हूं। मेरे पास एक घटक है जो प्रॉपर-राउटर<Link/> से किसी ऑब्जेक्ट को प्राप्त करता है । जब भी उपयोगकर्ता इस घटक के अंदर एक 'अगले' बटन पर क्लिक करता है, तो मैं ऑब्जेक्ट को मैन्युअल रूप से आमंत्रित करना चाहता हूं ।<Link/>

अभी, मैं बैकिंग इंस्टेंस का उपयोग करने के लिए रेफ्स का उपयोग कर रहा हूं और मैन्युअल रूप से 'ए' टैग पर क्लिक करता हूं जो उत्पन्न करता है।<Link/>

प्रश्न: क्या लिंक (जैसे this.props.next.go) को मैन्युअल रूप से लागू करने का एक तरीका है ?

यह मेरे पास वर्तमान कोड है:

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

यह वह कोड है जो मैं करना चाहूंगा:

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

जवाबों:


199

प्रतिक्रिया रूटर v4 - पुनर्निर्देशित घटक (2017/04/15 अपडेट किया गया)

V4 अनुशंसित तरीका आपके रेंडर विधि को पुनर्निर्देशित करने के लिए अनुमति देता है। यह निर्धारित करने के लिए राज्य या प्रॉप्स का उपयोग करें कि क्या रीडायरेक्ट घटक को दिखाने की आवश्यकता है (जो तब ट्रिगर को रीडायरेक्ट करता है)।

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

संदर्भ: https://reacttraining.com/react-router/web/api/Redirect

प्रतिक्रिया रूटर v4 - संदर्भ रूटर संदर्भ

आप Routerप्रतिक्रिया के घटक के संपर्क में आने वाले संदर्भ का भी लाभ उठा सकते हैं ।

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 /> हुड के नीचे काम करता है।

संदर्भ: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js#L46,L60

अभिक्रिया राउटर v4 - बाह्य रूप से इतिहास की वस्तु

यदि आपको अभी भी v2 के कार्यान्वयन के समान कुछ करने की आवश्यकता है, तो आप निर्यात की स्थिरांक BrowserRouterके historyरूप में एक प्रति बना सकते हैं । नीचे एक मूल उदाहरण दिया गया है, लेकिन यदि आवश्यक हो तो आप इसे अनुकूलन प्रॉप्स के साथ इंजेक्ट करने के लिए रचना कर सकते हैं। जीवनचक्र के साथ विख्यात केवेट हैं, लेकिन यह हमेशा राउटर को रेंडर करना चाहिए, जैसे v2 में। यह एक एक्शन फंक्शन से एपीआई अनुरोध के बाद रीडायरेक्ट के लिए उपयोगी हो सकता है।

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

नवीनतम BrowserRouterविस्तार करने के लिए: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

प्रतिक्रिया रूटर v2

browserHistoryउदाहरण के लिए एक नई स्थिति पुश करें :

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

संदर्भ: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfCompords.md


7
hashHistory.push ( '/ नमूना'); यदि आप ब्राउज़र के बजाय hashHistory का उपयोग कर रहे हैं
sanath_p

1
यह विशेष रूप से उपयोग कर रहा containerElement = के रूप में सामग्री-ui पुस्तकालय में उपयोगी है {<= के लिए लिंक "/" />} करता है हमेशा नहीं लिंक आह्वान
विशाल Disawar

2
रीडायरेक्ट विकल्प के साथ ध्यान दें कि आपको पुश निर्दिष्ट करना होगा (यानी <रीडायरेक्ट पुश />)। डिफ़ॉल्ट रूप से यह एक ऐसा रिप्लेसमेंट करेगा, जो एक लिंक को मैन्युअल रूप से लागू करने के समान नहीं है
aw04


1
रीडायरेक्ट मेरे लिए काम नहीं कर रहा है, लेकिन withRouter के साथ aw04 सॉल्यूशन अधिक सरल है और काम कर रहा है
स्टैकडेव

90

रिएक्टर राउटर 4 में एक राउटर एचओसी शामिल है जो आपको historyऑब्जेक्ट के माध्यम से पहुंच प्रदान करता है 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)

9
यह मेरे लिए काम किया और यह सबसे सरल समाधान की तरह दिखता है।
रूबाइकट

5
यह सबसे अच्छा उपाय है। मैं यह नहीं समझता कि इसके इतने कम वोट क्यों हैं।
बेनोइट

1
हां, आप कुछ बार लिंक पर क्लिक कर सकते हैं और ब्राउज़र बैक काम नहीं करेगा। आपको वास्तव में वापस जाने के लिए कुछ समय के लिए ब्राउज़र बैक पर क्लिक करने की आवश्यकता होगी
व्लादिस्लाव टेरेशिन

अगर ((this.props.location.pathname + this.props.location.search) == navigateToPath!) {...}: @VladyslavTereshyn आप कुछ सशर्त तर्क जोड़ सकते हैं
MattWeiler

15

में संस्करण 5.x , तो आप उपयोग कर सकते हैं useHistoryकी हुक 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>
  );
}

यह सबसे अच्छा उपाय है। यदि आप कुछ सशर्त तर्क जोड़ते हैं, तो आप इतिहास में डुप्लिकेट प्रविष्टियों से बच सकते हैं जब कोई उपयोगकर्ता एक ही बटन को कई बार क्लिक करता है:if ((routerHistory.location.pathname + routerHistory.location.search) !== navigateToPath) { routerHistory.push(navigateToPath); }
MattWeiler

मुझे historyचर घोषित करने की जरूरत थी , useHistory().push
हुकिंग

यह सबसे आधुनिक प्रतिक्रिया-ईशीय समाधान लगता है।
यंगेजे

8

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

या आप इस पर क्लिक करने की कोशिश भी कर सकते हैं (अधिक हिंसक समाधान):

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

कोड की लाइनों के रूप में, आपका उत्तर बेहतर होगा यदि आप विवरणों की नकल करते हैं और यहां अपना उत्तर समझाते हैं। इसके अलावा, assignयह एक संपत्ति नहीं है, यह एक समारोह है।
वायर्डपाइरी

(लेकिन आप अभी भी एक फ़ाइल की एक विशिष्ट लाइन के लिए एक लिंक है)। कृपया अपने उत्तर में विशिष्ट सुझाव शामिल करें, न कि केवल एक लिंक।
वायर्डप्रैरी

आपके उत्तर के लिए धन्यवाद @grechut हालांकि, मैं यह सुनिश्चित करना चाहता हूं कि दस्तावेज़ राउटर के बारे में कुछ भी नहीं जानता है। मैं जिस व्यवहार की उम्मीद कर रहा हूं वह यह है: 'यदि उपयोगकर्ता सही तीर पर क्लिक करता है, तो अगले फ़ंक्शन को लागू करें'। अगला फ़ंक्शन एक लिंक हो सकता है या नहीं।
एलन सूजा

मेरे पास रिएक्ट (FB और Google रीडायरेक्ट्स के साथ लॉगिन स्क्रीन) के बाहर संभाले गए कुछ पृष्ठ हैं, इसलिए मुझे "BrowserHistory.push ('/ home') के बाद से उन पृष्ठों के लिए नौसेना में इसकी आवश्यकता थी;" केवल URL बदल दिया, यह पृष्ठों को रूट करने में असमर्थ था। धन्यवाद।
डेबोरा

7
यह पेज @grechut को पुनः लोड करेगा, प्रतिक्रिया रूटर के साथ एक आवेदन के लिए एक वांछित व्यवहार नहीं।
Abhas

2

ठीक है, मुझे लगता है कि मैं उसके लिए एक उचित समाधान खोजने में सक्षम था।

अब, मैं दस्तावेज़ <Link/>में प्रस्ताव के रूप में भेजने के बजाय, <NextLink/>प्रतिक्रिया-राउटर लिंक के लिए एक कस्टम आवरण भेज रहा हूं । ऐसा करने से, मैं लिंक संरचना के हिस्से के रूप में सही तीर रखने में सक्षम हूं, जबकि अभी भी दस्तावेज़ ऑब्जेक्ट के अंदर रूटिंग कोड से परहेज कर रहा हूं।

अद्यतन कोड इस प्रकार दिखता है:

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

पुनश्च : यदि आप प्रतिक्रिया-राउटर के नवीनतम संस्करण का उपयोग कर रहे हैं तो आपको this.context.router.transitionToइसके बजाय उपयोग करने की आवश्यकता हो सकती है this.context.transitionTo। यह कोड प्रतिक्रिया-राउटर संस्करण 0.12.X के लिए ठीक काम करेगा।


2

राउटर 4

आप v4 में संदर्भ के माध्यम से पुश विधि को आसानी से लागू कर सकते हैं:

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

जहाँ संदर्भ है:

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

का उपयोग करते हुए BrowserRouter, मेरे घटकों के संदर्भ ऑब्जेक्ट में routerऑब्जेक्ट नहीं है। क्या मैं गलत हूं?
पिलाऊ

क्या आप घटक (ऊपर दूसरा ब्लॉक) में संदर्भ सेट कर रहे हैं?
क्रिस

में chiming के लिए धन्यवाद! अंततः यह मेरे लिए काम किया router: React.PropTypes.object.isRequired:। मुझे नहीं पता कि यह isRequiredकुंजी के बिना काम क्यों नहीं किया । इसके अलावा, संदर्भ <Link>प्राप्त करने में सक्षम प्रतीत होता है history, लेकिन मैं इसे दोहरा नहीं सकता था।
पिलाऊ

एक दिलचस्प - यदि आप एक कोडपेन लगाते हैं, तो मैं इसे डीबग करने में आपकी मदद कर सकता हूं यदि आप अभी भी अटक रहे हैं
क्रिस

ऐसा लगता है कि आप this.props.history.push()React Router v4 में उपयोग कर सकते हैं । मैं केवल यह पाया कि प्रॉपर राउटर हालांकि में प्रॉम्प्ट का निरीक्षण करके। यह काम करने लगता है लेकिन मुझे यकीन नहीं है कि यह एक अच्छा विचार है।
sean_j_roberts

-1

फिर से यह JS है :) यह अभी भी काम करता है ....

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

<Link id="something" to={/somewhaere}> the link </Link>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.