क्लाइंट रूटिंग (प्रतिक्रिया-राउटर का उपयोग करके) और सर्वर-साइड रूटिंग


108

मैं सोच रहा था और मैं क्लाइंट और सर्वर के बीच रूटिंग के साथ भ्रमित हूं। मान लीजिए कि मैं वेब ब्राउज़र पर अनुरोध भेजने से पहले सर्वर-साइड रेंडरिंग के लिए ReactJS का उपयोग करता हूं, और एसपीए के रूप में ताज़ा किए बिना पृष्ठों के बीच स्विच करने के लिए क्लाइंट-साइड रूटिंग के रूप में प्रतिक्रिया-राउटर का उपयोग करता हूं।

मन में क्या आता है:

  • मार्गों की व्याख्या कैसे की जाती है? उदाहरण के लिए, होम पेज ( /home) से पोस्ट पेज तक अनुरोध ( /posts)
  • राउटिंग कहाँ जाता है, सर्वर-साइड या क्लाइंट पर?
  • यह कैसे पता चलता है कि यह कैसे संसाधित होता है?

1
मेरा सुझाव है कि ब्राउज़र में इतिहास एपीआई पर पढ़ना।
वायर्डपाइरी

जवाबों:


137

ध्यान दें, यह उत्तर रिएक्ट राउटर संस्करण 0.13.x को कवर करता है - आगामी संस्करण 1.0 ऐसा लगता है कि इसमें काफी अलग कार्यान्वयन विवरण होंगे

सर्वर

यह server.jsप्रतिक्रिया-राउटर के साथ एक न्यूनतम है :

var express = require('express')
var React = require('react')
var Router = require('react-router')

var routes = require('./routes')

var app = express()

// ...express config...

app.use(function(req, res, next) {
  var router = Router.create({location: req.url, routes: routes})
  router.run(function(Handler, state) {
    var html = React.renderToString(<Handler/>)
    return res.render('react_page', {html: html})
  })
})

जहां routesमॉड्यूल रूट की सूची निर्यात करता है:

var React = require('react')
var {DefaultRoute, NotFoundRoute, Route} = require('react-router')

module.exports = [
  <Route path="/" handler={require('./components/App')}>
    {/* ... */}
  </Route>
]

हर बार सर्वर से एक अनुरोध किया जाता है, आप Routerआने वाले URL के साथ उसके स्थिर स्थान के रूप में कॉन्फ़िगर किए गए एकल-उपयोग का उदाहरण बनाते हैं , जिसे उचित मिलान वाले मार्गों को सेट करने के लिए मार्गों के पेड़ के खिलाफ हल किया जाता है, जो शीर्ष-स्तर के साथ वापस बुलाता है। रूट हैंडलर का प्रतिपादन किया जाना और प्रत्येक स्तर पर बाल मार्गों का मिलान करना। जब आप <RouteHandler>मिलान किए गए चाइल्ड रूट को रेंडर करने के लिए रूट हैंडलिंग कंपोनेंट के भीतर कंपोनेंट का उपयोग करते हैं तो यही सलाह ली जाती है ।

यदि उपयोगकर्ता ने जावास्क्रिप्ट बंद कर दिया है, या इसे लोड करना धीमा हो रहा है, तो वे जिस भी लिंक पर क्लिक करेंगे, वह सर्वर पर फिर से आ जाएगा, जो फिर से ऊपर के रूप में हल हो गया है।

ग्राहक

यह client.jsप्रतिक्रिया-राउटर के साथ एक न्यूनतम है (समान मार्गों को फिर से उपयोग करते हुए):

var React = require('react')
var Router = require('react-router')

var routes = require('./routes')

Router.run(routes, Router.HistoryLocation, function(Handler, state) {
  React.render(<Handler/>, document.body)
})

जब आप कॉल करते हैं Router.run(), तो यह पर्दे के पीछे आपके लिए एक राउटर इंस्टेंस बनाता है, जो हर बार जब आप ऐप के चारों ओर नेविगेट करते हैं, तो जैसा कि URL क्लाइंट पर गतिशील हो सकता है, जैसा कि सर्वर पर विरोध किया जाता है, जहां एक एकल अनुरोध है निश्चित URL।

इस मामले में, हम उपयोग कर रहे हैं HistoryLocation, जो Historyएपीआई का उपयोग करता है यह सुनिश्चित करने के लिए कि जब आप पीछे / आगे बटन दबाते हैं तो सही काम होता है। वहाँ भी है HashLocationजो hashइतिहास प्रविष्टियाँ बनाने के लिए URL बदलता है और window.onhashchangeनेविगेशन को ट्रिगर करने के लिए घटना सुनता है ।

जब आप प्रतिक्रिया-राउटर के <Link>घटक का उपयोग करते हैं, तो आप इसे एक toप्रोप देते हैं जो मार्ग का नाम है, साथ ही किसी भी मार्ग paramsऔर queryडेटा की जरूरत है। <a>इस घटक द्वारा प्रदान की गई एक है onClickहैंडलर जो अंततः कॉल router.transitionTo()रंगमंच की सामग्री आप लिंक है, जो इस तरह दिखता है दे दी है साथ रूटर उदाहरण पर:

  /**
   * Transitions to the URL specified in the arguments by pushing
   * a new URL onto the history stack.
   */
  transitionTo: function (to, params, query) {
    var path = this.makePath(to, params, query);

    if (pendingTransition) {
      // Replace so pending location does not stay in history.
      location.replace(path);
    } else {
      location.push(path);
    }
  },

एक नियमित लिंक के लिए यह अंततः location.push()आपके द्वारा उपयोग किए जा रहे स्थान प्रकार पर कॉल करता है, जो इतिहास को स्थापित करने के विवरण को संभालता है इसलिए पीछे और आगे के बटन के साथ नेविगेट करना काम करेगा, फिर कॉल करता है router.handleLocationChange()कि राउटर को यह बताएं कि यह संक्रमण के साथ आगे बढ़ सकता है नया URL पथ।

राउटर तब router.dispatch()नए URL के साथ अपनी खुद की विधि कहता है , जो यह निर्धारित करने के विवरण को संभालता है कि कौन से कॉन्फ़िगर किए गए मार्ग URL से मेल खाते हैं, फिर मिलान किए गए मार्गों के लिए मौजूद किसी भी संक्रमण हुक को कॉल करता है । जब आपके रूट को आपकी पसंद की चीजें नहीं मिल रही हों, तो संक्रमण को खत्म करने की क्षमता के साथ, जब आप रूट को नेविगेट या नेविगेट करने वाले हों, तो कुछ कार्रवाई करने के लिए आप अपने किसी भी मार्ग संचालकों पर इन संक्रमण हुक को लागू कर सकते हैं।

यदि संक्रमण को समाप्त नहीं किया गया था, तो अंतिम चरण उस कॉलबैक को कॉल करना है जो आपने Router.run()शीर्ष-स्तरीय हैंडलर घटक और राज्य ऑब्जेक्ट के साथ URL और मिलान किए गए मार्गों के विवरण के साथ दिया था। शीर्ष-स्तरीय हैंडलर घटक वास्तव में Routerस्वयं उदाहरण है, जो शीर्ष-सबसे रूट हैंडलर का मिलान करता है जो मिलान किया गया था।

जब आप क्लाइंट पर एक नए URL पर जाते हैं, तो उपरोक्त प्रक्रिया को फिर से चलाया जाता है।

उदाहरण परियोजनाओं


3
तो मैं शायद कह सकता हूँ कि क्लाइंट राउटिंग को जावास्क्रिप्ट (जो प्रतिक्रिया-राउटर कोड है) द्वारा नियंत्रित किया जाता है अगर यह प्रस्तुत करता है। जब भी मैं ब्राउजर एड्रेस बार पर एंटर करता हूं या पेज को रिफ्रेश करता हूं या जेएस को डिसेबल करता हूं, तो सर्वर साइड रूटिंग को हैंडल करेगा। दूसरी ओर, जब जावास्क्रिप्ट को वर्तमान पृष्ठ पर तैयार किया जाता है, तो रूटिंग क्लाइंट साइड द्वारा नियंत्रित किया जाएगा। क्या मैं सही से समझ पाया?
हार्टमन

9
मार्गों के मॉड्यूल में क्या है var routes = require('./routes')क्या यह मार्गों की सूची है? मैंने एक्सप्रेस राउटर का उपयोग किया है, लेकिन एसओ पर यहां यह उदाहरण रिएक्टर राउटर के साथ सर्वर साइड रेंडरिंग स्थापित करने का एकमात्र उदाहरण लगता है, इसलिए यह अच्छा होगा यदि यह एक पूर्ण कोड उदाहरण है
svnm

2
यह मार्गों की एक सूची होनी चाहिए। मैं उस बारे में एक नोट जोड़ूंगा और कुछ लिंक उदाहरण परियोजनाओं के लिए।
जॉनी बुकानन

2
इसलिए यदि राउटर-राउटर सर्वर साइड रूटिंग का ध्यान रखता है तो डेटाबेस से बात कौन करता है? क्या होता है सर्वर साइड रूटिंग? कल्पना करें कि हम एक देशी मोबाइल ऐप के लिए REST API प्रदान करना चाहते हैं। उसकी देखभाल कौन करता है?
मोर्टेजा शाहरीरी निया

1
उत्तर नए react-routerसंस्करण के कारण पुराना है । कृपया इसे अपडेट करें।
oleh.meleshko

26

1.0 के साथ, रिएक्ट-राउटर इतिहास मॉड्यूल पर सहकर्मी निर्भरता के रूप में निर्भर करता है । यह मॉड्यूल ब्राउजर में रूटिंग से संबंधित है। डिफ़ॉल्ट रूप से प्रतिक्रिया-रूटर एचटीएमएल 5 इतिहास एपीआई (का उपयोग करता है pushState, replaceState), लेकिन आप इसे कॉन्फ़िगर हैश आधारित मार्ग का उपयोग कर सकते हैं (नीचे देखें)

मार्ग से निपटने अब पर्दे के पीछे किया जाता है, और मार्ग बदल जाने पर ReactRouter रूट हैंडलर्स को नए प्रॉप्स भेजता है। onUpdateजब भी कोई रूट बदलता है, तो राउटर को एक नया प्रोप कॉलबैक मिलता है <title>, उदाहरण के लिए पेजव्यू ट्रैकिंग या अपडेट करने के लिए उपयोगी है ।

क्लाइंट (HTML5 रूटिंग)

import {Router} from 'react-router'
import routes from './routes'

var el = document.getElementById('root')

function track(){
  // ...
}

// routes can be children
render(<Router onUpdate={track}>{routes}</Router>, el)

ग्राहक (हैश-आधारित रूटिंग)

import {Router} from 'react-router'
import {createHashHistory} from 'history'
import routes from './routes'

var el = document.getElementById('root')

var history = createHashHistory()

// or routes can be a prop
render(<Router routes={routes} history={history}></Router>, el)

सर्वर

सर्वर पर, हम उपयोग कर सकते हैं ReactRouter.match, यह सर्वर रेंडरिंग गाइड से लिया गया है

import { renderToString } from 'react-dom/server'
import { match, RoutingContext } from 'react-router'
import routes from './routes'

app.get('*', function(req, res) {
  // Note that req.url here should be the full URL path from
  // the original request, including the query string.
  match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message)
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
      res.status(200).send(renderToString(<RoutingContext {...renderProps} />))
    } else {
      res.status(404).send('Not found')
    }
  })
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.