İstemci Yönlendirme (react-yönlendiriciyi kullanarak) ve Sunucu Tarafı Yönlendirme


108

Düşünüyordum ve İstemci ile Sunucu arasındaki yönlendirmeyle karıştırıldım. İsteği web tarayıcısına geri göndermeden önce sunucu tarafında işleme için ReactJS kullandığımı ve SPA olarak yenilemeden sayfalar arasında geçiş yapmak için istemci tarafı yönlendirme olarak react-yönlendiriciyi kullandığımı varsayalım.

Akla gelen şudur:

  • Rotalar nasıl yorumlanıyor? Örneğin, Ana sayfadan ( /home) Gönderiler sayfasına ( /posts) bir istek
  • Yönlendirme, sunucu tarafında veya istemcide nereye gidiyor?
  • Nasıl işlendiğini nasıl biliyor?

1
Tarayıcılarda Geçmiş API'sini okumanızı öneririm.
WiredPrairie

Yanıtlar:


137

Bu cevabın React Router 0.13.x sürümünü kapsadığını unutmayın - gelecek sürüm 1.0 , önemli ölçüde farklı uygulama ayrıntılarına sahip olacak gibi görünüyor

Sunucu

Bu, server.jsreact-router'da minimumdur :

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

routesModülün bir Rotalar listesini verdiği yer :

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

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

Sunucuya her istekte bulunulduğunda Router, gelen URL ile statik konum olarak yapılandırılmış tek kullanımlık bir örnek oluşturursunuz ; bu, uygun eşleşen yolları ayarlamak için yol ağacına göre çözülür ve üst düzey ile geri çağırır. işlenecek yol işleyicisi ve her düzeyde hangi alt yolların eşleştiğinin bir kaydı. Bunu kullandığınızda danışılan şey budur.<RouteHandler> eşleşen bir alt yol oluşturmak için bileşeni bir yol işleme bileşeni içinde .

Kullanıcının JavaScript'i kapatılmışsa veya yüklenmesi yavaşsa, tıkladıkları herhangi bir bağlantı sunucuya tekrar vurur ve bu da yukarıdaki gibi tekrar çözülür.

Müşteri

Bu, client.jsreact-router'da minimumdur (aynı yollar modülünü yeniden kullanarak):

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

Aradığın zaman Router.run() , perde arkasında sizin için bir Yönlendirici örneği oluşturur ve bu, uygulama içinde her gezindiğinizde yeniden kullanılır, çünkü tek bir isteğin bir sabit URL.

Bu durumda, geri / ileri düğmesine bastığınızda doğru şeyin gerçekleştiğinden emin olmak için API'yiHistoryLocation kullanan kullanıyoruz . Ayrıca , geçmiş girişleri yapmak için URL'yi değiştiren ve navigasyonu tetiklemek için olayı dinleyen bir de vardır .HistoryHashLocationhashwindow.onhashchange

Tepki-yönlendiricinin kullandığınızda <Link>bileşeni, bunu bir vermek tobir güzergah adıdır pervane, artı paramsve queryveri rota ihtiyaçlarını. <a>Bu bileşen tarafından işlenen bir sahiptir onClicksonuçta çağırır işleyicisi router.transitionTo()şuna benzeyen bağlantıyı verdi sahne ile yönlendirici örneğinde:

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

Normal bir bağlantı için bu, nihayetinde location.push()hangi Konum türünü kullanıyor olursanız olun, bu da geçmişin ayarlanmasının ayrıntılarını yönetir, böylece geri ve ileri düğmeleriyle gezinmenin işe yarayacağını ve ardından router.handleLocationChange()yönlendiriciye geçişle devam edebileceğini bildirmek için geri arar . yeni URL yolu.

Yönlendirici daha sonra router.dispatch(), yapılandırılmış yollardan hangisinin URL ile eşleştiğini belirleme ayrıntılarını işleyen yeni URL ile kendi yöntemini çağırır, ardından eşleşen yollar için mevcut geçiş kancalarını çağırır . Bu geçiş kancalarını, bir rota uzaklaşmak veya navigasyon yapmak üzereyken bazı şeyler yapmak için herhangi bir rota işleyicinize uygulayabilir ve işler hoşunuza gitmediğinde geçişi iptal etme özelliğine sahiptir.

Geçiş iptal edilmediyse, son adım, Router.run()üst düzey işleyici bileşeniyle verdiğiniz geri aramayı ve URL'nin tüm ayrıntılarını ve eşleşen yolları içeren bir durum nesnesini çağırmaktır . Üst düzey işleyici bileşeni, Routereşleştirilen en üstteki yol işleyicisini oluşturmayı işleyen aslında örneğin kendisidir.

İstemcide yeni bir URL'ye her gittiğinizde yukarıdaki süreç yeniden çalıştırılır.

Örnek projeler


3
Bu yüzden, eğer mevcutsa, istemci yönlendirmesinin javascript (react-router kodu) tarafından işlendiğini söyleyebilirim. Tarayıcı adres çubuğuna enter tuşuna bastığımda veya sayfayı yenilediğimde veya JS'yi devre dışı bıraktığımda, yönlendirmeyi sunucu tarafı halledecek. Diğer yandan javascript mevcut sayfada hazır olduğunda, yönlendirme istemci tarafında yapılacaktır. Doğru anladım mı?
heartmon

9
Güzergahlar modülünde neler var var routes = require('./routes')Bu bir güzergah listesi mi? Ekspres yönlendiriciyi kullandım, ancak SO üzerindeki bu örnek, React Router ile sunucu tarafı oluşturmanın tek örneği gibi görünüyor, bu nedenle tam bir kod örneği olsaydı iyi olurdu
svnm

2
Bir yol listesi olmalıdır. Bununla ilgili bir not ve örnek projelere bazı bağlantılar ekleyeceğim.
Jonny Buchanan

2
Öyleyse, react-router sunucu tarafı yönlendirmeyle ilgilenirse, veritabanına kim konuşuyor? sunucu tarafı yönlendirmeye ne olur? Yerel bir mobil uygulama için bir REST API sağlamak istediğimizi düşünün. Bununla kim ilgileniyor?
Morteza Shahriari Nia

1
Yeni react-routersürüm nedeniyle cevap güncel değil . Lütfen güncelleyin.
oleh.meleshko

26

1.0 ile React-Router, peerDependency olarak geçmiş modülüne bağlıdır . Bu modül tarayıcıda yönlendirme ile ilgilenir. React-Router varsayılan olarak HTML5 Geçmiş API'sini ( pushState, replaceState) kullanır, ancak bunu karma tabanlı yönlendirme kullanacak şekilde yapılandırabilirsiniz (aşağıya bakın)

Rota işleme artık perde arkasında yapılır ve ReactRouter, rota değiştiğinde Rota işleyicilerine yeni sahne öğeleri gönderir. Yönlendirici, bir onUpdaterota değiştiğinde yeni bir destek geri aramasına sahiptir , bu <title>, örneğin, sayfa görüntülemenin izlenmesi veya güncellenmesi için yararlıdır .

İstemci (HTML5 yönlendirme)

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)

İstemci (karma tabanlı yönlendirme)

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)

Sunucu

Sunucuda kullanabiliriz ReactRouter.match, bu sunucu oluşturma kılavuzundan alınmıştır.

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')
    }
  })
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.