Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Router v5附带代码拆分,并使用服务器端呈现进行数据预取_Javascript_Reactjs_Webpack_Lazy Loading_Server Side Rendering - Fatal编程技术网

Javascript React Router v5附带代码拆分,并使用服务器端呈现进行数据预取

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,因为这有点困难,因为

我有一个项目,其中使用react router v3只有一个原因。原因是需要使用数据预取进行服务器端渲染,最方便的方法是在
对象
数组
中保持集中式路由配置,并循环匹配元素以从服务器端的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