ক্লায়েন্ট রাউটিং (প্রতিক্রিয়া-রাউটার ব্যবহার করে) এবং সার্ভার-সাইড রাউটিং


108

আমি ভাবছিলাম এবং ক্লায়েন্ট এবং সার্ভারের মধ্যে রাউটিংয়ের সাথে আমি বিভ্রান্ত হয়ে পড়েছি। ধরুন আমি ওয়েব ব্রাউজারে অনুরোধটি ফেরত পাঠানোর আগে সার্ভার-সাইড রেন্ডারিংয়ের জন্য রিঅ্যাকটজেএস ব্যবহার করি এবং এসপিএ হিসাবে রিফ্রেশ না করে পৃষ্ঠাগুলির মধ্যে স্যুইচ করতে ক্লায়েন্ট-সাইড রাউটিং হিসাবে রিঅ্যাক্ট-রাউটার ব্যবহার করি।

যা মনে আসে তা হ'ল:

  • রুটগুলি কীভাবে ব্যাখ্যা করা হয়? উদাহরণস্বরূপ, হোম পৃষ্ঠা ( /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আগত ইউআরএলটিকে তার স্থিতিশীল অবস্থান হিসাবে কনফিগার করা একক-ব্যবহারের উদাহরণ তৈরি করেন যা উপযুক্ত ম্যাচযুক্ত রুটগুলি সেট করার জন্য রুটের গাছের বিরুদ্ধে সমাধান করা হয়, শীর্ষ স্তরের সাথে ফিরে কল করে রুট হ্যান্ডলারটি উপস্থাপন করতে হবে এবং প্রতিটি স্তরে কোন শিশু রুটের সাথে মিল রয়েছে তার একটি রেকর্ড। যখন আপনি <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 টি ক্লায়েন্টের উপর গতিশীল হতে পারে opposed স্থির ইউআরএল।

এই ক্ষেত্রে, আমরা পিছনে / ফরোয়ার্ড বোতামটি চাপলে সঠিক জিনিস ঘটে তা নিশ্চিত করতে APIHistoryLocation ব্যবহার করে যা আমরা ব্যবহার করছি Historyuses এখানে একটা ব্যাপার HashLocationযা URL টি পরিবর্তন hashকরতে ইতিহাস এন্ট্রি এবং শোনা করার 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()রাউটারকে জানাতে এটি পুনরায় স্থানান্তরিত হওয়ার সাথে এগিয়ে যেতে পারে calls নতুন ইউআরএল পাথ।

রাউটারটি তারপরে router.dispatch()নতুন ইউআরএল এর সাথে নিজস্ব পদ্ধতি কল করে , যা কনফিগার করা রুটগুলির মধ্যে কোনটি ইউআরএলের সাথে মিলে যায় তা নির্ধারণের বিশদ পরিচালনা করে, তারপরে ম্যাচযুক্ত রুটের জন্য উপস্থিত কোনও রূপান্তর হুককে কল করে। কোনও রুট যখন নেভিগেট করা হবে বা নেভিগেট করা হবে তখন কিছু ব্যবস্থা নেওয়ার জন্য আপনি আপনার যেকোন রুট হ্যান্ডলারের উপর এই রূপান্তর হুক প্রয়োগ করতে পারেন, যদি জিনিসগুলি আপনার পছন্দ মতো না হয় তবে ট্রানজিশনটি বাতিল করতে হবে।

যদি ট্রানজিশনটি বাতিল করা না হয় তবে চূড়ান্ত পদক্ষেপটি হ'ল Router.run()শীর্ষস্থানীয় হ্যান্ডলার উপাদান এবং ইউআরএল এবং ম্যাচযুক্ত রুটের সমস্ত বিবরণ সহ একটি রাষ্ট্রের সাথে আপনি যে কলব্যাকটি দিয়েছিলেন তা কল করা call শীর্ষ-স্তরের হ্যান্ডলার উপাদানটি প্রকৃতপক্ষে Routerনিজেই উদাহরণস্বরূপ, যা সর্বাধিক সর্বাধিক রুট হ্যান্ডলারের সাথে মিলিত হয় nd

উপরের প্রক্রিয়াটি প্রতিবার ক্লায়েন্টের নতুন URL এ নেভিগেট করার সময় পুনরায় চালানো হবে।

উদাহরণ প্রকল্প


3
সুতরাং আমি সম্ভবত বলতে পারি যে ক্লায়েন্ট রাউটিং জাভাস্ক্রিপ্ট দ্বারা পরিচালিত হয় (যা প্রতিক্রিয়া-রাউটার কোড হয়) যদি তা উপস্থাপন করে। আমি যখনই ব্রাউজারের অ্যাড্রেস বারে প্রবেশ করুন বা পৃষ্ঠাটি রিফ্রেশ করব বা জেএস অক্ষম করব তখন সার্ভার সাইডটি রাউটিংটি পরিচালনা করবে। অন্যদিকে, যখন জাভাস্ক্রিপ্ট বর্তমান পৃষ্ঠায় প্রস্তুত হবে তখন রাউটিংটি ক্লায়েন্টের পক্ষ থেকে পরিচালিত হবে। আমি কি ঠিক বুঝতে পেরেছি?
হার্টমন

9
রুটগুলির মডিউলে কী রয়েছে var routes = require('./routes')এটি কি রুটের একটি তালিকা? আমি এক্সপ্রেস রাউটারটি ব্যবহার করেছি তবে এসওতে এই উদাহরণটিই কেবল প্রতিক্রিয়া রাউটারের সাথে সার্ভার সাইড রেন্ডারিং স্থাপনের একমাত্র উদাহরণ বলে মনে হচ্ছে, তাই এটি যদি পুরো কোডের উদাহরণ হয় তবে ভাল হবে
svnm

2
এটি রুটের তালিকা হওয়া উচিত। আমি সে সম্পর্কে একটি নোট এবং উদাহরণগুলির কয়েকটি লিঙ্ক যুক্ত করব।
জনি বুচানান

2
সুতরাং যদি প্রতিক্রিয়া-রাউটার সার্ভার সাইড রাউটিংয়ের যত্ন নেয় তবে ডাটাবেসে কথা বলার কাজটি কে করে? সার্ভার সাইড রাউটিংয়ে কী ঘটে? কল্পনা করুন আমরা একটি নেটিভ মোবাইল অ্যাপ্লিকেশনটির জন্য একটি REST এপিআই সরবরাহ করতে চাই। কে এই যত্ন নেয়?
মোর্তেজা শাহরিয়ারি নিয়া

1
নতুন react-routerসংস্করণের কারণে উত্তরটি পুরানো হয়েছে । এটি আপডেট করুন।
oleh.meleshko

26

১.০ সহ, প্রতিক্রিয়া-রাউটার পিয়ার-নির্ভরতা হিসাবে ইতিহাস মডিউলটির উপর নির্ভর করে । এই মডিউলটি ব্রাউজারে রাউটিংয়ের বিষয়ে কাজ করে। ডিফল্টরূপে প্রতিক্রিয়া-রাউটারটি HTML5 ইতিহাসের API ( pushState, replaceState) ব্যবহার করে তবে আপনি এটি হ্যাশ-ভিত্তিক রাউটিং ব্যবহার করতে কনফিগার করতে পারেন (নীচে দেখুন)

রুট হ্যান্ডলিং এখন পর্দার আড়ালে সম্পন্ন হয়েছে, এবং রেক্টরউটার রুট হ্যান্ডলারের কাছে রুট পরিবর্তনের সময় নতুন প্রসেস প্রেরণ করে। রাউটারের একটি নতুন onUpdateপ্রোপ কলব্যাক রয়েছে যখনই কোনও রুট পরিবর্তন হয়, পৃষ্ঠা ভিউ ট্র্যাকিংয়ের জন্য দরকারী বা <title>উদাহরণস্বরূপ, আপডেট করা ।

ক্লায়েন্ট (এইচটিএমএল 5 রাউটিং)

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')
    }
  })
})
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.