当前位置: 首页 > 科技观察

使用ReactRouter4构建通用JavaScript应用

时间:2023-03-13 14:20:16 科技观察

ReactRouter是React世界中非常流行的库。它依靠地址栏上的请求URL和浏览器的操作历史来呈现不同的页面内容以保持显示,然后将您的应用程序同步到用户界面页面。Shiny新手最近,ReactRouter版本4进入了测试版。偏偏偏偏,这次ReactRouter的发布是对之前版本的完全重写,这导致了许多破坏性的API更改。版本4的核心思想是“声明式可组合性”?—它采用了使React如此出色的组件概念并将其应用于路由。ReactRouter4的每一部分都是一个React组件:Router、Route、Link等。ReactRouter的开发者之一RyanFlorence亲自制作了一个短视频来介绍最新的ReactRouter。这个视频已经被很多人推荐了:视频:https://youtu.be/a4kqMQorcnE背景如何?新版本的ReactRouter提供了一个新的网页,里面有很多实用的代码示例,但是没有提供如何实现的例子在服务器端使用ReactRouter渲染基于React的页面。最近做的一个项目,SEO友好和网站速度快是重中之重,那么有必要在客户端渲染整个页面吗?它与示例页面上的所有示例都一样吗?这是不可取的。我们将使用Express服务器在后台呈现React页面。在他的介绍视频中,Ryan有一个App组件,它可以使用componentDidMount生命周期方法从一些API获取数据以初始化其状态。但是异步数据获取操作完成后,组件会更新显示数据。但这在服务器端渲染App组件时没有效果:当你使用renderToString时,调用组件的render方法后会同步创建带有HTML代码的字符串。componentDidMount永远不会被调用。因此,如果我们使用Ryan视频中的示例在后台渲染App组件,它只会生成一条“正在加载...”消息。解决方案作为概念证明解决方案,我创建了一个演示应用程序,它基本上从视频中重新创建了Ryan的示例,但使用了服务器端渲染。该应用程序使用GitHubAPI获取有关Gist代码片段的数据:codeshow您可以在Github上找到演示应用程序的源代码:https://github.com/technology-ebay-de/universal-react-router4简介简而言之,这就是我所做的...server/index.js这是每次将HTTP请求发送到Express服务器时运行的代码:constroutes=['/','/g/:gistId'];app.get('*',(req,res)=>{constmatch=routes.reduce((acc,route)=>matchPath(req.url,route,{exact:true})||acc,null);if(!match){res.status(404).send(render());return;}fetch('https://api.github.com/gists').then(r=>r.json()).then(gists=>res.status(200).send(render((),要点))).catch(err=>res.status(500).send(render());});app.listen(3000,()=>console.log('演示程序p侦听端口3000'));(注意:这只是一个摘录,您可以在GitHub上找到完整的源代码)在第1-4行,我为应用程序定义了一个路由数组。数组的第一个元素是针对主页的初始请求,没有选择Gists。第二个路由用于显示选定的Gist。在第6行,我的Express应用程序被告知处理任何可以与星号匹??配的请求。在第7行,我使用ReactRouter的matchPath函数来简化路由数组;结果是一个匹配对象,其中包含有关匹配路由的信息以及可以从URL路径转换的任何参数。在第8-11行,如果有不匹配的路由,我将呈现一个错误页面,上面写着:“找不到页面”。这里的render函数只是对React的renderToString的包装,将基页的HTML代码(、、等)添加到React组件的HTML周围。在第12–22行,我从GitHubAPI获取数据以填充App状态并呈现App组件。最明显的是第17行,我在其中使用StaticRouter组件来初始化ReactRouter。Router组件类型是服务器呈现场景的绝佳选择。它永远不会改变位置,这正是我们在这个场景中所需要的,因为它在背景上,我们只渲染一次,它不会直接对用户交互做出反应。第23行将捕获处理期间生成的错误消息以呈现错误页面。我的App组件如下所示:exportdefault({gists})=>(

{gists?gists.map(gist=>({gist.description||'[无描述]'})):(

正在加载...

)}
{gists&&((g.id===match.params.gistId)}/>)}/>)}
),document.getElementById('app'));(→GitHub上的完整代码)这比服务器端代码简单多了!第1行的渲染函数是ReactDOM渲染函数。它将我的React组件的呈现布局附加到DOM节点。第2行使用BrowserRouter(而不是我用于服务器端渲染的StaticRouter)。在第3行,我使用要点数据实例化App组件,而不是通过GitHubAPI获取数据。要点数据来自浏览器DOM中的全局变量,后端通过