React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React服务器组件

React 服务器组件的使用方法详解

作者:托儿所夜十三

最近,React 服务器组件受到了广泛的关注和热捧,这是因为 React 服务器组件允许开发人员将与组件相关的任务外包给服务器,在本文中,我们将讨论什么是 React 服务器组件,以及如何将它们集成到构建应用程序中,需要的朋友可以参考下

简介

最近,React 服务器组件受到了广泛的关注和热捧。这是因为 React 服务器组件允许开发人员将与组件相关的任务外包给服务器。这样,开发人员就无需分发捆绑的 JavaScript 和外部 API 查询,以便将组件水化,同时也避免了会导致客户端应用程序延迟增加的情况。 在本文中,我们将讨论什么是 React 服务器组件,以及如何将它们集成到构建应用程序中。

什么是服务器组件?

服务器组件是 React 18 中引入的新功能,也是 Next.js 13 中的默认功能。服务器组件本质上是一种从服务器检索数据并在服务器上渲染的组件类型。这些内容随后会以客户端应用程序可以呈现的格式流式传输到客户端应用程序中。
服务器组件以自定义格式呈现,这种格式没有标准协议,但类似于 JSON 格式。反应 DOM 可识别这种格式,并在识别后对其进行适当的呈现。

引入 React 服务器组件概念的问题陈述

我们将创建一个场景来介绍服务器组件的概念。可以将产品页面结构化如下:

const ProductPage = ({ productId })=> {
    return (
        <>
            <ProductDetails productId={productId}>    
                <ProductItem productId={productId} />
                <MatchedItems productId={ productId } />
            <ProductDetails>
        </>
    )
}

现在我们有很多方法去获取组件中需要的数据,如下所示,一次性获取获取到组件所需的数据:

const ProductPage = ({ productId })=> {
    const data = fetchContentsFromAPI();
    return (
        <>
            <ProductDetails details={data.details} productId={productId}>    
                <ProductItem item={data.product} productId={productId} />
                <MatchedItems items={data.matchedItems} productId={productId} />
            <ProductDetails>
        </>
    )
}

使用这种方法效果很好,而且有其优点,例如:

不过,它也可能带来一些问题,例如:

为了实现单一责任,我们可以重组父组件,以如下方式显示组件:

const ProductDetails = ({productId, children}) => {
    const details = fetchProductDetails(productId);
    return (
        <>
            {{ children }}
        </>
    )
}
const ProductItem = ({productId}) => {
    const item = fetchProductItem(productId);
    return (...)
}
const MatchedItems = ({productId}) => {
    const items = fetchMatchedItems(productId);
    return (...)
}
const ProductPage = ({ productId })=> {
    return (
        <>
            <ProductDetails productId={productId}>    
                <ProductItem productId={productId} />
                <MatchedItems productId={productId} />
            <ProductDetails>
        </>
    )
}

使用这种方法效果很好,而且有其优点,例如:

但是,它可能会产生一些问题,例如:

这些方法各有利弊,但有一个共同的局限性。这个限制是,这两种方法都需要从客户端向服务器调用 API,这会造成客户端和服务器之间的高延迟。

正是这一限制促使 React 团队引入了服务器组件:服务器上的组件。由于服务器组件存在于服务器上,因此与在应用程序客户端渲染的组件相比,它们可以更快地进行 API 调用并快速渲染。

虽然最初是为了解决高延迟的限制,但新的应用也随之出现。由于组件驻留在服务器上,它们可以访问服务器基础设施,这意味着它们可以连接到数据库并对其进行查询。

React 服务器组件与客户端组件的区别

服务器组件和客户端组件的一个主要区别是,服务器组件在服务器上呈现组件,而客户端组件在客户端上呈现。

通常,对于客户端的 React 应用程序来说,当用户从服务器请求网页时,服务器会将网页(Javascript 文件)响应给浏览器。浏览器下载数据(Javascript 文件)并用于构建网页。 另一方面,客户端组件会发送到客户端,从而增加了应用程序的捆绑大小(客户端组件是典型的传统 React 组件)。

另一个区别在于它们的呈现环境,这赋予了它们不同的属性,具体解释如下:

React 服务器组件与 React 服务器端呈现(SSR)的区别。

React 中的服务器端呈现(SSR)是指应用程序将服务器上的 React 组件转化为完全呈现给客户端的静态 HTML 页面的能力。 另一方面,React 服务器组件(React Server Components)通过一个中介结构(类似于 JSON 格式的协议)与 SSR 协作,从而在不向客户端交付任何捆绑包的情况下实现渲染。

服务器组件案例研究。

我们将说明如何在传统的 React 应用程序和 Next.js 应用程序中使用服务器组件。

在 React 应用程序中使用服务器组件。 在典型的 React 应用程序中,服务器组件就像普通的 React 组件一样。

请注意,要在带有 .tsx 文件的 typescript 组件中使用 async/await,需要将 typescript 版本升级到 5.1.1。要了解更多信息,请访问此处

下面是一个服务器组件的示例:

// Server Component
 const BlogPost = async({id, isEditing}) => {
 const post = await db.posts.get(id);
  return (
    <div>
      <h1>{post.title}</h1>
      <section>{post.body}</section>
    </div>
  );
}

客户端组件看起来就像普通的 React 组件,但在组件文件中添加了 use client 指令。从技术上讲,use client 指令声明了服务器组件和客户端组件之间的边界。

// A client component
'use client'
import React, { useState } from "react";
import { v4 as uuidv4 } from 'uuid';
const PostEditor = ({ blogPost }) => {
  const [post, setPost] = useState<any>({
    id: uuidv4(),
    title: blogPost.title,
    content: blogPost.content,
  })
  const onChange = (type: any, value: any)=> {
    switch(type){
      case "title":
        setPost({...post, title: value})
        break;
      case "content":
        setPost({...post, content: value})
        break;
      default:
        break
    }
  }
  const submitPost = ()=> {
    // save blog post
  };
  return (
    <div>
      <div className="md:mx-auto px-6 md:px-0 mt-10 md:w-9/12">
        <h1 className="my-4 text-center">Create Post</h1>
        <form onSubmit={submitPost}>
          <div className="mt-8">
            <label className="text-white mb-2"> Title </label>
            <input 
              type="text" placeholder="" 
              value={post.title}
              required 
              onChange={(e)=> onChange("title", e.target.value)}
            />
          </div>
          <div className="mt-8">
            <label className="text-white mb-2">
              Add your Blog content
            </label>
            <textarea
              value={post.content}
              required
              onChange={(e)=> onChange("content", e.target.value)}
            ></textarea>
          </div>
          <div className="flex justify-end mt-8">
            <button
              type="submit"
              className="px-4 py-4 bg-[#0e9f64] c-white border-radius"
            >
              Create Post
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};
export default PostEditor;

在使用服务器和客户端组件时,有一些特定的规则需要了解:

服务器组件不能导入到客户端组件中,但客户端组件可以导入到服务器组件中。我们将用下面的例子来说明如何将客户端组件导入到服务器组件中:

// Server Component
import db from 'db'; 
import NoteEditor from 'NoteEditor';
async function BlogPost({id, isEditing}) {
  const post = await db.posts.get(id);
  return (
    <div>
      <h1>{post.title}</h1>
      <section>{post.body}</section>
      {isEditing 
        ? <PostEditor blogPost={post} />
        : null
      }
    </div>
  );
}

在上面的代码中,我们将 PostEditor(客户端组件)导入了服务器组件。

当客户端组件位于服务器组件内时,服务器组件可以作为子 prop 传递给客户端组件。

const ServerComponent1 = () => {
    return (
        <ClientComponent>
            <ServerComponent2 />
        </ClientComponent>
    )
}

在 Next 应用程序中使用服务器组件

默认情况下,服务器组件是在 Next 13 中新引入的 App 目录中创建的普通 React 组件。

// Server Component
 const BlogPost = async({id, isEditing}) => {
 const post = await db.posts.get(id);
  return (
    <div>
      <h1>{post.title}</h1>
      <section>{post.body}</section>
    </div>
  );
}

Next 13 中的客户端组件看起来像普通的 React 组件,但在组件文件中添加了 use client 指令。

// A client component
'use client'
import React, { useState } from "react";
import { v4 as uuidv4 } from 'uuid';
const PostEditor = ({ blogPost }) => {
  const [post, setPost] = useState<any>({
    id: uuidv4(),
    title: blogPost.title,
    content: blogPost.content,
  })
  const onChange = (type: any, value: any)=> {
    switch(type){
      case "title":
        setPost({...post, title: value})
        break;
      case "content":
        setPost({...post, content: value})
        break;
      default:
        break
    }
  }
  const submitPost = ()=> {
    // save blog post
  };
  return (
    <div>
      <div className="md:mx-auto px-6 md:px-0 mt-10 md:w-9/12">
        <h1 className="my-4 text-center">Create Post</h1>
        <form onSubmit={submitPost}>
          <div className="mt-8">
            <label className="text-white mb-2"> Title </label>
            <input 
              type="text" placeholder="" 
              value={post.title}
              required 
              onChange={(e)=> onChange("title", e.target.value)}
            />
          </div>
          <div className="mt-8">
            <label className="text-white mb-2">
              Add your Blog content
            </label>
            <textarea
              value={post.content}
              required
              onChange={(e)=> onChange("content", e.target.value)}
            ></textarea>
          </div>
          <div className="flex justify-end mt-8">
            <button
              type="submit"
              className="px-4 py-4 bg-[#0e9f64] c-white border-radius"
            >
              Create Post
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};
export default PostEditor;

React 服务器组件的利与弊

我们将介绍在开发中使用服务器组件的优点以及缺点。

优点:

缺点:

结论

在本文中,我们介绍了 React 中的服务器组件,并讨论了它们的用途和优点。React 服务器组件使我们能够以一种全新的方式在 React 应用程序中将客户端和服务器端渲染组件的优点结合起来。

以上就是React 服务器组件的使用方法详解的详细内容,更多关于React服务器组件的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文