Javascript React Router v5附带代码拆分,并使用服务器端呈现进行数据预取
我有一个项目,其中使用react router v3只有一个原因。原因是需要使用数据预取进行服务器端渲染,最方便的方法是在Javascript React Router v5附带代码拆分,并使用服务器端呈现进行数据预取,javascript,reactjs,webpack,lazy-loading,server-side-rendering,Javascript,Reactjs,Webpack,Lazy Loading,Server Side Rendering,我有一个项目,其中使用react router v3只有一个原因。原因是需要使用数据预取进行服务器端渲染,最方便的方法是在对象或数组中保持集中式路由配置,并循环匹配元素以从服务器端的API获取数据。稍后的数据将与响应HTML一起传递给客户机,并存储在JSON格式字符串的变量中 应用程序也使用代码拆分,但是通过使用babel插件转换,确保在服务器端忽略,我可以直接获取组件,而不是延迟加载,并且本机的导入方法将仅在客户端使用 然而,上述结构不适用于react router v5,因为这有点困难,因为
对象
或数组
中保持集中式路由配置,并循环匹配元素以从服务器端的API获取数据。稍后的数据将与响应HTML一起传递给客户机,并存储在JSON格式字符串的变量中
应用程序也使用代码拆分,但是通过使用babel插件转换,确保在服务器端忽略
,我可以直接获取组件,而不是延迟加载,并且本机的导入
方法将仅在客户端使用
然而,上述结构不适用于react router v5,因为这有点困难,因为我不能使用@loadable/components
,正如react router官方文档所示。根据我的观察,@loadable/components
只是在服务器端生成HTML,而不是给我实现负责服务器端逻辑的fetch
方法的组件
因此,我想问一下webpack+react router v5+ssr+数据预取+redux+代码拆分的良好结构
我知道这很复杂,没有通用的解决方案,但我可能错了
感谢您的指导或建议。我从未尝试过
@loadable/components
,但我使用自定义的代码拆分实现做过类似的事情(SSR+代码拆分+数据预取),我相信您应该改变数据预取方法
如果我没弄错的话,您的问题是您试图干预正常的React渲染过程,提前推断渲染中将使用哪些组件,以及应该预取哪些数据。这样的干预/推断并不是React API的一部分,尽管我看到不同的人使用一些未记录的内部React来实现它,但从长远来看,这一切都是脆弱的,并且容易出现像您这样的问题
我认为,一种更好的防弹方法是将SSR作为几个正常的渲染过程来执行,在每个过程中收集要预取的数据列表,获取它们,然后从一开始就使用更新的状态重复渲染。我正在努力想出一个明确的解释,但让我试着用这样的例子
比如,组件的上下文
,或者使用React的上下文API创建一个单独的组件)
您可以使用ReactDOMServer.renderToString(..)
对整个应用程序进行非常基本的SSR
当渲染器到达渲染组件时(代码>):
const ssrContext={
//这是“全局状态”的初始内容。我使用自定义库
//使用上下文API来管理它;但是使用Redux也可以做类似的事情。
国家:{},
};
让标记;
const ssrStart=Date.now();
for(让round=0;round0&&wait Promise.race([
承诺。全部解决(ssrContext.pending),
timer.timer(超时)。然后(()=>false),
]);
如果(!ok)中断;
//在这里,您应该使用“ssrContext.pending”承诺解析的数据,
//并将其放置在“ssrContext.state”的正确路径中,然后再继续
//在我的例子中,我的全局状态管理库
//处理好了,所以我不需要在这里明确地做。
}
//这里的“ssrContext.state”应该包含要发送到的Redux存储内容
//客户端,而“标记”是相应的呈现HTML。
依赖于异步数据的组件内部的逻辑有点像这样:
函数组件(){
//尝试从Redux存储获取必要的异步。
常量数据=使用选择器(…);
//react路由器不提供用于访问上下文的挂钩,
//在我的情况下,我是通过我的
//无论如何,得到它不应该是一个问题。
const ssrContext=usesrcontext();
//Redux存储中没有必要的数据。
如果(!数据){
//我们在服务器上。
如果(上下文){
ssrContext.dirty=true;
ssrContext.pending.push(
//这是一个承诺,解决了我们在这里需要的数据。
);
//我们在客户端。
}否则{
//分派操作将数据加载到Redux存储,
//根据您的设置而定。
}
}
返回数据(
//返回需要“数据”的完整组件渲染
//用于渲染。
) : (
//返回适当的占位符(例如“加载”指示器)。
);
}
Hi@Sergey,谢谢您的回复。如果你能用一个小例子进一步解释一下,我将不胜感激。它不应该是完整的解决方案,也可以是一些图表。我认为这个问题的解决方案对其他人也很有价值。嗨@ArenHovsepyan,我更新了我的答案,添加了两个代码片段。希望这能让事情变得更清楚。嗨@Sergey,基本上我理解的是我们可以制作高阶函数,并基于一些变量触发数据获取,对吗?嗯。。。不确定,你把高阶函数叫做什么?主要的一点是,您可以进行非常简单的SSR渲染,所有组件都依赖于异步数据,将它们需要的数据写入到上下文对象中,然后wai