客户端路由(使用react-router)和服务器端路由 [英] Client Routing (using react-router) and Server-Side Routing

查看:391
本文介绍了客户端路由(使用react-router)和服务器端路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在想,我对Client和Server之间的路由感到困惑。假设我在将请求发送回Web浏览器之前使用ReactJS进行服务器端呈现,并使用react-router作为客户端路由在页面之间切换而不刷新为SPA。

I have been thinking and I am confused with the routing between Client and Server. Suppose I use ReactJS for server-side rendering before sending the request back to web browser, and use react-router as a client-side routing to switch between pages without refreshing as SPA.

我想到的是:


  • 如何解释路线?例如,从主页( / home )到帖子页面的请求( / posts

  • 路由在服务器端或客户端上的位置?

  • 它如何知道如何处理?

  • How are the routes interpreted? For example, a request from Home page (/home) to Posts page (/posts)
  • Where does the routing go, on server-side or client?
  • How does it know how it is processed?

推荐答案

注意,这个答案涵盖了React Router版本0.13.x - 即将推出的版本1.0 看起来会有明显不同的实现细节

Note, this answer covers React Router version 0.13.x - the upcoming version 1.0 looks like it will have significantly different implementation details

这是一个最小的 server.js with react-router:

This is a minimal server.js with react-router:

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

路线模块导出路径列表:

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

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

每次向服务器发出请求时,都会创建一次性使用路由器实例配置了传入的URL作为其静态位置,该路由树根据路由树解析以设置适当的匹配路由,使用顶级路由处理程序回调要呈现并记录每个级别匹配的子路由。当您在路由处理组件中使用< RouteHandler> 组件来呈现匹配的子路由时,这就是所咨询的。

Every time a request is made to the server, you create a single-use Router instance configured with the incoming URL as its static location, which is resolved against the tree of routes to set up the appropriate matched routes, calling back with the top-level route handler to be rendered and a record of which child routes matched at each level. This is what's consulted when you use the <RouteHandler> component within a route handling component to render a child route which was matched.

如果用户关闭了JavaScript,或者加载速度很慢,他们点击的任何链接都会再次点击服务器,如上所述再次解决。

If the user has JavaScript turned off, or it's being slow to load, any links they click on will hit the server again, which is resolved again as above.

这是一个带有react-router的最小 client.js (重新使用相同的路由模块):

This is a minimal client.js with react-router (re-using the same routes module):

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的服务器上。

When you call Router.run(), it creates a Router instance for you behind the scenes, which is re-used every time you navigate around the app, as the URL can be dynamic on the client, as opposed to on the server where a single request has a fixed URL.

在这种情况下,我们使用 HistoryLocation ,它使用 历史记录 API 确保在按下后退/前进按钮时正确的事情发生。还有一个 HashLocation ,它会更改URL hash 以创建历史记录条目并侦听 window.onhashchange 事件以触发导航。

In this case, we're using the HistoryLocation, which uses the History API to make sure the right thing happens when you hit the back/forward button. There's also a HashLocation which changes the URL hash to make history entries and listens to the window.onhashchange event to trigger navigation.

当你使用react-router的< Link> 组件时,你给它一个 prop这是路由的名称,加上任何 params 查询路由所需的数据。此组件呈现的< a> 有一个 onClick 处理程序,最终调用路由器。 transitionTo()在路由器实例上带有你给出链接的道具,如下所示:

When you use react-router's <Link> component, you give it a to prop which is the name of a route, plus any params and query data the route needs. The <a> rendered by this component has an onClick handler which ultimately calls router.transitionTo() on the router instance with the props you gave the link, which looks like this:

  /**
   * 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路径。

For a regular link this ultimately calls location.push() on whichever Location type you're using, which handles the details of setting up history so navigating with the back and forward buttons will work, then calls back to router.handleLocationChange() to let the router know it can proceed with transitioning to the new URL path.

然后路由器调用它自己的 router.dispatch()方法带有新URL,它处理确定哪些配置的路由与URL匹配的详细信息,然后调用任何匹配路由的转换挂钩。您可以在任何路由处理程序上实现这些转换挂钩,以便在路由即将导航或导航到路径时执行某些操作,并且能够在不符合您喜欢的情况下中止转换。

The router then calls its own router.dispatch() method with the new URL, which handles the details of determining which of the configured routes match the URL, then calls any transition hooks present for the matched routes. You can implement these transition hooks on any of your route handlers to take some action when a route is about to be navigated away from or navigated to, with the ability to abort the transition if things aren't to your liking.

如果转换没有中止,最后一步是调用你给 Router.run()的回调顶级处理程序组件和状态对象,包含URL和匹配路由的所有详细信息。顶级处理程序组件实际上是 Router 实例本身,它处理渲染匹配的最顶层路由处理程序。

If the transition wasn't aborted, the final step is to call the callback you gave to Router.run() with the top-level handler component and a state object with all the details of the URL and the matched routes. The top-level handler component is actually the Router instance itself, which handles rendering the top-most route handler which was matched.

每次导航到客户端上的新URL时,都会重新运行上述过程。

The above process is re-run every time you navigate to a new URL on the client.

  • React Router Mega Demo
  • Isomorphic Lab

这篇关于客户端路由(使用react-router)和服务器端路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆