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

React Server Component能否通过全局存储值更新?

问题

我有一个React Server Component(RSC),它可以访问Redux存储的初始值,甚至能向Redux存储分发action,初始值设为10。我知道在Next.js中可通过router.refresh()重渲染RSC,客户端组件点击按钮能成功递增计数,但RSC在重渲染后仍显示初始值10。请问RSC是否永远无法访问更新后的全局存储(如Redux)?

相关代码

store/counterSlice.ts

const initialState: CounterState = {
  value: 10,
};

app/serverComponent.tsx

export default async function ServerComponent() {
  const data = await fetchSomeData();
  store.dispatch(updateTestData(data)); // 此代码可正常运行

  const counter = store.getState().counter; // 可获取初始值10

  console.log('this log is shown in the server');

  return (
    <main className={styles.main}>
      <div className={styles.description}>
        {/* 显示初始值10 */}
        <p>Current Count: {counter.value}</p>
      </div>
    </main>
  );
}

app/clientComponent.tsx

'use client';

import { useDispatch, useSelector } from 'react-redux';
import { AppDispatch, RootState } from '@/store';
import { increment } from '@/store/counterSlice';
import { useRouter } from 'next/navigation';

export default function ClientComponent({
  children,
}: {
  children: React.ReactNode;
}) {
  const dispatch = useDispatch<AppDispatch>();
  const count = useSelector((state: RootState) => state.counter.value);
  const router = useRouter();

  const handleIncrementCounter = () => {
    dispatch(increment());
    // 重渲染服务端组件
    router.refresh();
  };

  return (
    <div id='with-font-container'>
      {/* 此值可正确订阅并随存储变化更新 */}
      <p>Current Count: {count}</p>
      <button onClick={handleIncrementCounter}>Increment Count</button>
      {children}
    </div>
  );
}

app/page.tsx

export default function Home() {
  return (
    <div className='bg-black text-3xl'>
      <ClientComponent>
        {/* 此错误为Next13已知bug */}
        {/* @ts-expect-error Server Component */}
        <ServerComponent />
      </ClientComponent>
    </div>
  );
}

解答

不是“永远无法访问”,但你的代码里出现这种情况是核心机制导致的:

  • 服务端与客户端Redux实例完全隔离:服务端每次渲染RSC时,使用的是服务端环境的Redux存储实例,和客户端浏览器里的Redux存储是完全独立的两个环境。客户端点击按钮dispatch的increment action,只会修改客户端的存储状态,服务端的存储始终保持初始值10。router.refresh()触发的是服务端重新渲染RSC,自然读取的还是服务端存储的初始值。

  • router.refresh()不同步客户端状态到服务端:这个方法的作用是让服务端重新生成当前页面的HTML并发送到客户端,但它不会把客户端的Redux状态传递给服务端,服务端也没有自动同步客户端状态的机制。

可行的解决思路

  1. 将状态持久化到服务端存储:客户端dispatch action时,同时调用API把最新状态保存到数据库、Redis等服务端可访问的存储中。RSC重渲染时,通过fetch或直接读取服务端存储获取最新值,而不是依赖服务端的Redux实例。

  2. 通过客户端组件传递状态:如果不需要服务端渲染最新状态,可以让客户端组件把更新后的count作为props传递给RSC。但注意这种情况下,RSC的内容实际是由客户端控制展示的,并非服务端渲染的最新状态。

  3. 拆分职责:让Redux只负责客户端的状态管理,RSC所需的状态直接从数据源(如API)获取,不依赖全局Redux存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:47:48