ReactJS - renderToReadableStream() 方法



渲染组件是 React Web 开发领域中一项非常基础的任务。一种方法是使用 renderToReadableStream 函数将 React 组件渲染为流。

什么是 renderToReadableStream?

React 提供了 renderToReadableStream 方法用于 React 组件的服务器端渲染。我们可以使用此方法将我们的 React 树作为 HTML 渲染到可读 Web 流中。它允许我们以流式格式传输在线内容,而不是一次创建和分发整个网页。

它是如何工作的?

当我们调用 renderToReadableStream 时,我们会传入一个我们想要渲染为 Web 流的 React 组件。此组件应表示完整文档,包括 HTML 结构。该函数还接受可选参数,这些参数可用于自定义流的行为。

语法

const stream = await renderToReadableStream(reactNode, optional)

参数

  • reactNode − 它是要渲染为 HTML 的 React 节点。例如,像 <App /> 这样的 JSX 元素。App 组件应该渲染 <html> 标签,因为它被创建为表示完整内容。

  • optional − 它是一个包含流选项的对象。

返回值

renderToReadableStream 方法返回一个 Promise。如果 shell 成功渲染,则此 Promise 解析为包含生成的 HTML 内容的可读 Web 流。如果渲染失败,则 Promise 被拒绝,让用户有机会提供备用 shell。

示例

示例 - 加载内容

我们可以在 React 中以不同的方式使用 renderToReadableStream 方法 -

流内容 − 为了使我们的网站更友好,我们可以根据加载情况显示它的各个部分。

import React, { useState, useEffect } from 'react';
import { renderToReadableStream } from 'react-dom/server';

const App = () => {
   const [content, setContent] = useState([]);
   useEffect(() => {
   
      // loading content progressively
      const loadDataProgressively = async () => {
         await new Promise(resolve => setTimeout(resolve, 1000));
         setContent(['Loading the content...']);
         await new Promise(resolve => setTimeout(resolve, 2000));
         setContent(['Loading the content...', 'More content...']);
         await new Promise(resolve => setTimeout(resolve, 2000));
         setContent(['All content is loaded!']);
      };
   
      loadDataProgressively();
   }, []);
   
   return (
      <div>
         {content.map((item, index) => (
            <p key={index}>{item}</p>
         ))}
      </div>
   );
};

const stream = renderToReadableStream(<App />);

输出

content loading

添加自定义脚本 − 我们可以引入自定义脚本来自定义网页显示时的行为。

// Inside our component
useEffect(() => {
   
   // Create a new element
   const script = document.createElement('script');
   script.text = 'console.log("Custom Script has been Executed");';
   document.body.appendChild(script);
}, []);

处理错误 − 在显示内容之前,我们可以处理服务器错误,甚至更改错误状态代码。

// Inside the component
const [error, setError] = useState(null);

useEffect(() => {
   try {
      // Code that can throw an error
   } catch (err) {
      setError(err);
   }
}, []);

return (
   <div>
      {error ? <p>Error is: {error.message}</p> : null}
   </div>
);

中止渲染 − 在必要时,我们可以停止服务器渲染并让客户端处理其余的渲染。要中止渲染,我们可以根据条件简单地停止渲染内容。这是一个简单的示例 -

const [abortRendering, setAbortRendering] = useState(false);

useEffect(() => {
      if (abortRendering) {
         // Stop rendering
      }
   }, []);

return (
   <div>
      {abortRendering ? <p>Rendering aborted</p> : <p>Content goes here</p>}
   </div>
);

示例 - 带有帖子的博客应用

此应用程序是一个简单的博客应用程序,显示博客文章列表。每个帖子都将有一个标题和内容。BlogApp 组件将帖子数组作为 prop 并使用 Post 组件渲染它们。因此,我们将有两个组件 Post 和 BlogApp。Post 组件将显示具有标题和内容的单个博客帖子。BlogApp 将是主组件,它获取帖子数组并渲染具有标题和内容的博客。该应用程序将生成一个包含帖子列表的博客。

import { renderToReadableStream } from 'react-render-stream';

// Define the Post and BlogApp components
const Post = ({ title, content }) => (
   <div>
      <h2>{title}</h2>
      <p>{content}</p>
   </div>
);
const BlogApp = ({ posts }) => (
   <div>
      <h1>My Blog</h1>
      {posts.map((post, index) => (
         <Post key={index} {...post} />
      ))}
   </div>
);

// Create some sample blog posts
const posts = [
   { title: 'React Streams', content: 'Understanding renderToReadableStream.' },
   { title: 'State Management', content: 'Using Redux for state.' },
   // Add more posts as needed
];

// Render the BlogApp component
const App = () => (
   <div>
      <BlogApp posts={posts} />
   </div>
);

const stream = await renderToReadableStream(<App />);

输出

my blog

示例 - 电子商务产品目录

在此应用程序中,我们将拥有一个显示产品列表的电子商务产品目录。每个产品都有名称、价格和描述。ECommerceApp 组件将产品数组作为 prop 并使用 Product 组件渲染它们。我们将有两个组件:Product 和 ECommerceApp。Product 组件显示具有名称、价格和描述的单个产品。ECommerceApp 组件将是主组件,它获取产品数组并渲染产品目录。该应用程序将生成一个包含产品列表的电子商务目录。

import { renderToReadableStream } from 'react-render-stream';

// Define the components
const Product = ({ name, price, description }) => (
   <div>
      <h2>{name}</h2>
      <p>{description}</p>
      <p>${price}</p>
   </div>
);
const ECommerceApp = ({ products }) => (
   <div>
   <h1>Our Products</h1>
   {products.map((product, index) => (
      <Product key={index} {...product} />
   ))}
   </div>
);

// Sample products
const products = [
   { name: 'Laptop', price: 999, description: 'Powerful computing on the go.' },
   { name: 'Smartphone', price: 599, description: 'Stay connected anytime, anywhere.' },
];

// Render the ECommerceApp component
const App = () => (
   <div>
      <ECommerceApp products={products} />
   </div>
);

const stream = await renderToReadableStream(<App />);

输出

our products

总结

renderToReadableStream 是一种将 React 组件渲染为流的强大方法。它允许我们创建更具响应性的应用程序并改善用户体验。

reactjs_reference_api.htm
广告