You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时选用Server Actions、客户端组件与服务端组件及数据共享方案

组件间共享auth_token的最优方案及各技术适用场景

我正尝试理解如何在组件间共享数据,希望将auth_token存储在内存中并在整个应用内共享。目前我有两种可选方案:

  • Context Provider
  • Prop Drilling

混合使用这两种方案可实现预期需求,但我直觉认为这并非正确做法。我搭建了一个测试沙箱,包含若干客户端组件与服务端组件来验证数据传递效果:

测试代码

page.tsx

import React from 'react';
import ContextCC from "./contenxt_cc";
import ContextSC from "./context_sc";
import ContextChildCC from './context_child_cc';

const Page: React.FC = () => {
  const data = "token.AWd12b112d12d11.123123123";
  return (
    <div>
      <p> This is a server component - {data} </p>
      <ContextCC data={data}>
        <ContextSC data={data} />
        <ContextChildCC />
      </ContextCC>
    </div>
  );

};

export default Page;

context_cc.tsx

'use client'
import React, { useContext } from 'react';
import AppContext from './app_context';

export default function ContextCC({ children, data }: { children: React.ReactNode, data: string }) { 
  const sharedData = {
    sharedMessage: data,
  }
  return (
    <AppContext.Provider value={sharedData}>
      <div>
        <p> This is a client component - {sharedData.sharedMessage} </p>
        { children }
      </div>
    </AppContext.Provider>
  );
}

context_sc.tsx

export default function ContextSC({data}: { data: string }) {
  return (
    <div>
      <p> This is a server component - { data }</p>
    </div>
  );
}

context_child_cc.tsx

"use client";
import { useContext } from "react";
import AppContext from "./app_context";
import { printAuthToken } from "./server_action";
import { useState } from "react";

export default function ContextChildCC() {
  const [serverRes, setServerRes] = useState("");
  const context = useContext(AppContext);
  const action = async () => {
    const result = await printAuthToken(context.sharedMessage)
    setServerRes(result.msg);
  }
  return(
    <div>
      <p> This is a child client component - {context.sharedMessage} </p>
      <p> {serverRes} </p>
      <button onClick={action}> Send </button>
    </div>
  )
}

测试可得到预期输出,但我认为应有更优的数据传递方式。例如服务端组件传递auth-token时,需手动传递props,易因遗漏导致故障。我还尝试了Server Actions,感觉流程更顺畅:

server_action.ts

"use server"

export async function printAuthToken(authToken: string) {
  console.log(authToken);
  return { msg: "This is a response from a server action - " + authToken }
}

我想明确:

  1. 是否应优先使用Server Actions而非服务端组件?
  2. 更核心的是,Server Actions、服务端组件、客户端组件各自的适用场景是什么?

问题解答

1. 是否优先使用Server Actions而非服务端组件?

不是,两者解决的是完全不同的问题,不存在“优先选择”的说法,需要根据具体场景搭配使用。

2. 各技术的适用场景

服务端组件(Server Components)

  • 核心优势:在服务器端渲染,无需发送JS到客户端,减少包体积;直接访问服务器资源(数据库、内部API等),无需额外API请求。
  • 适用场景:
    • 渲染不需要交互的静态内容(比如文章详情、产品列表);
    • 需要直接从服务器获取数据的页面/组件(避免客户端额外请求);
    • 处理敏感逻辑或数据(比如权限校验、获取auth_token的初始值),避免暴露到客户端。

客户端组件(Client Components)

  • 核心优势:拥有完整的React交互能力(状态管理、事件监听、useEffect等),可以直接操作DOM。
  • 适用场景:
    • 需要用户交互的组件(表单、按钮、弹窗、导航菜单);
    • 依赖浏览器API的功能(比如localStorage、地理位置、WebSocket);
    • 需要使用Context、Redux等客户端状态管理工具共享数据的场景(比如你的auth_token在客户端组件间共享)。

Server Actions

  • 核心优势:让客户端组件直接调用服务器端的异步函数,无需手动编写API接口,简化前后端交互流程;自动处理表单提交的状态(加载、错误),支持渐进式增强。
  • 适用场景:
    • 客户端需要触发服务器端操作(比如提交表单、修改数据、调用内部服务);
    • 传递敏感数据到服务器(比如你的auth_token提交验证),避免手动拼接API请求带来的安全风险;
    • 简化前后端交互逻辑,替代传统的API路由。

针对你的auth_token共享场景的优化建议

  • 初始的auth_token可以在服务端组件中获取(比如从请求头、数据库或会话中),然后通过Context Provider(客户端组件)传递给其他客户端组件,避免Prop Drilling;
  • 服务端组件如果需要使用auth_token,直接从服务器端获取即可,无需通过props传递(比如从会话中读取,而不是从父组件传);
  • 当客户端需要把auth_token发送到服务器执行操作时,使用Server Actions是更简洁的方案,无需手动处理API请求。

内容的提问来源于stack exchange,提问作者IdecEddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 04:54:54