如何使用 React-Router 的服务器端渲染中的 <Link> 标签更改 StaticRouter 的位置道具

Posted

技术标签:

【中文标题】如何使用 React-Router 的服务器端渲染中的 <Link> 标签更改 StaticRouter 的位置道具【英文标题】:How to change StaticRouter's location prop using the <Link> tag in Server Side Rendering with React-Router 【发布时间】:2018-05-03 04:52:04 【问题描述】:

已经有效的方法:

主页上的服务器端渲染。

什么不起作用:

通过单击&lt;Link&gt; 标签转到其他路由,从主页在其他其他路由上进行服务器端渲染。好吧,有点不工作,同时工作。

工作方式?:

如果您在单击&lt;Link&gt; 后查看页面的页面源,您将看到服务器端渲染获取的所有初始数据,但是它没有存储在客户端的reducer 中。

解决方案?:

通过大量时间和研究和询问,我得出的结论是,问题出在服务器端的StaticRouter。特别是 location 道具。此道具通过req.pathreq.url,我都尝试过并得到相同的结果。我将以req.path 为例。

让我们看看这里的这段代码:

console.log(req.path);
    const content = renderToString(
      <Provider store=store>
        <StaticRouter location=req.path context=context>
          <div>renderRoutes(routes)</div>
        </StaticRouter>
      </Provider>
    );

在这里,我们在将 req.path 传递给 location 属性之前注销它。这就是我认为告诉路由器将正确的数据加载到存储中并将其发送到客户端减速器的原因。

我将逐步说明应用流程发生的情况。

/ 路由加载console.log(req.path) 在服务器端显示此:

/

但是,例如,如果我单击 &lt;Link to="/users"&gt;Users&lt;/Link&gt;,控制台日志什么也不做。

现在我可以从这里刷新页面,然后它就可以工作了,数据已加载,console.log(req.path) 显示:

/users

我可以做的其他事情是直接转到localhost:3000/users 的路线,console.log(req.path) 将显示/users 并且数据正确加载。但这两种方式都不是真正的解决方案,只是因为它们以某种方式“绕过”了&lt;Link&gt; 标签。

问题是什么???:

我想知道如何使用&lt;Link&gt; 标签来更改req.pathreq.url,因为这是我所看到的问题,或者是否有可能。这样StaticRouter 中的location 属性会在&lt;Link&gt; 被点击时改变。

【问题讨论】:

【参考方案1】:

这段代码:

console.log(req.path);
    const content = renderToString(
      <Provider store=store>
        <StaticRouter location=req.path context=context>
          <div>renderRoutes(routes)</div>
        </StaticRouter>
      </Provider>
    );

在服务器端执行,它发生在您登陆站点、通过键入 url 直接访问某个页面或刷新页面时,因为在这些情况下,您“要求”服务器为您进行渲染。

&lt;Link&gt; 用于浏览器端的导航,它不要求服务器做任何事情,它都是在浏览器中执行的,所以它永远不会触发console.log(req.path);。除非您明确地这样做,例如,使用类似location.reload(); 的代码以编程方式刷新页面。在我看来,如果你觉得有必要做这样的事情,你就没有抓住重点。

s-s-r - 长话短说:

我们使用 s-s-r,因此当我们登陆页面时,我们不会等待初始 html 和初始数据。我们可以将服务器上的组件渲染成静态模型,而不是发送空白页面并让浏览器完成所有工作,然后将包含重新填充数据的页面发送到浏览器。当 bundle.js 出现时,浏览器从那时起接管,负责导航和加载交互所需的任何内容。

使用 s-s-r 的一些好处是 快速首次绘制,这可以带来更好的用户体验和潜在的更好的 SEO,因为爬虫更好地读取从服务器发送的静态模型而不是生成的动态模型客户。

【讨论】:

经过一些研究并认为这是我得出的结论,除了重新加载之外还有其他方法吗?因为在这种情况下,我还不如使用&lt;a&gt; 标签,或者只是通过操作加载数据客户端。但正如我所说,这可能是不可能的。那是你说的吗? 你想通过服务器重新加载来完成什么?如果它正在更新您的商店,获取数据,那是客户端应该对 Link 更改的导航状态执行的操作。 但这违背了做 s-s-r 的全部目的,不是吗? 不是,我们使用 s-s-r,所以当我们登陆页面时,我们不会等待初始 HTML 和初始数据。我们可以将服务器上的组件渲染成静态模型,而不是发送空白页面并让浏览器完成所有工作,然后将包含重新填充数据的页面发送到浏览器。当 bundle.js 出现时,浏览器从那时起接管,负责导航并加载交互所需的任何内容。 您能否将此添加到您的答案中,我会接受。此外,我发现在其他路线上进行 s-s-r 仍然有利于 SEO 的东西,比如爬虫等等。包括这个,我会接受答案并给你赏金

以上是关于如何使用 React-Router 的服务器端渲染中的 <Link> 标签更改 StaticRouter 的位置道具的主要内容,如果未能解决你的问题,请参考以下文章

服务器端 react-router 不会渲染我的路由

使用 react-router v4 和 express.js 进行服务器渲染

react-router

如何识别react-router Handler在它进入视图之前是NotFound?

React-router 多路由(React 组件)

使用 redux 和 react 进行异步服务器端渲染