使用 pipe() 时超过并发 React 渲染器的最大数量

Posted

技术标签:

【中文标题】使用 pipe() 时超过并发 React 渲染器的最大数量【英文标题】:Maximum number of concurrent React renderers exceeded when using pipe() 【发布时间】:2021-02-24 06:06:40 【问题描述】:

我有一个在 Kubernetes 中运行的带有 s-s-r 的 React 应用程序。几天没有重新启动 Pod 后,我收到此错误:https://reactjs.org/docs/error-decoder.html/?invariant=304。

我使用ReactDOMServer.renderToNodeStreampipe()并根据错误:

如果您没有正确销毁 React 提供的 Readable,就会发生这种情况。如果您不再想从中读取,请确保在其上调用 .destroy() 并且没有读到最后。 如果你使用 .pipe() 这应该是自动的。

这是我的服务器渲染器:

export function renderOnServer(res, controller) 
    return new Promise((resolve, reject) => 
        try 
            const index = controller.getIndexHTML();
            const view = controller.getView();

            const indexHTML = `<!DOCTYPE html>$ReactDOMServer.renderToStaticMarkup(index)`;
            const chunks = indexHTML.split("STREAMED_CONTENT");
            
            const firstChunk = chunks.shift();
            const lastChunk = chunks.shift();

            res.write(firstChunk);

            const stream = ReactDOMServer.renderToNodeStream(view);
            stream.pipe(res,  end : false );
            stream.on("end", () => 
                res.write(lastChunk);
                res.end();
                resolve();
            );
         catch(err) 
            reject(err);
        
    );

我使用pipe(),但我也处理end 事件,如代码中所示。这可能是问题的原因吗?还是应该关注代码的另一部分?

感谢任何帮助。谢谢。

【问题讨论】:

【参考方案1】:

您的代码似乎完全没问题。也许这是一些奇怪的 React 库的问题。你可以做以下事情:

    将 ReactJS 库和 NodeJS 更新到当前版本 尝试在“end”回调函数中销毁流:
stream.on("end", () => 
   stream.destroy(); // but I think it is not necessary
   res.write(lastChunk);
   res.end();
   resolve();
);
    你应该添加stream.on("error", () =&gt; something to do)回调函数

或者您可以用 renderToString 替换 renderToNodeStream 调用。它不如使用流的内存效率高,但在您的情况下更安全。

【讨论】:

以上是关于使用 pipe() 时超过并发 React 渲染器的最大数量的主要内容,如果未能解决你的问题,请参考以下文章

React 中的 Ag-grid 纯 JS 单元格渲染器

使用框架单元渲染器的 Ag 网格会在任何商店更改时不断重新渲染

AG-Grid React,无法在数据更改时更新自定义单元格渲染器。函数组件的行为与类组件不同

使用重新选择计算派生状态时如何避免 React 重新渲染

反应路由器本机渲染链接组件超过前一个

在 React 中使用 TypeScript 的 AG Grid 自定义单元格渲染器