React 共享状态:告别“祖传”Props,拥抱“真香”体验!🚀

React 共享状态:告别"祖传"Props,拥抱"真香"体验!🚀

各位掘友,请脑补这个经典剧情:

你正在快乐地写着 React 组件,突然发现:卧槽!这个 state 居然要在另一个组件里用到?!😱

于是你开始了传统艺能三选一:

  • Context → 为了一根香肠买回整头猪,用 Provider 把 App 裹成木乃伊
  • Redux → 恭喜你!为了一个变量,成功解锁 100 行模板代码的成就
  • Zustand/Jotai → 挺好,但总感觉为了点醋包了顿饺子

是不是已经开始 emo 了?别急,今天我就要安利一个让你直呼"真香"的解决方案!

隆重介绍:react-shared-states 🎉(此处应有掌声)

GitHub 指路:react-shared-states

来看个效果炸裂的 demo:

jsx 复制代码
import { useSharedState } from "react-shared-states";

function ComponentA() {
  const [count, setCount] = useSharedState("counter", 0);
  return <button onClick={() => setCount(count + 1)}>A: {count}</button>;
}

function ComponentB() {
  const [count, setCount] = useSharedState("counter", 0);
  return <button onClick={() => setCount(count + 1)}>B: {count}</button>;
}

// No provider needed!
function App() {
  return (
    <>
      <ComponentA />
      <ComponentB />
    </>
  );
}

点击 A,B 自动更新!就问你神不神奇?只需要一个相同的 key,世界大同!

这波操作堪称:一行代码,全球同步 🌍

吃瓜时间:这个库是怎么来的?🍉

某天,我基友兴冲冲地用起了 useBetween 这个库,代码写得飞起:

jsx 复制代码
const userData = useBetween(useUserData);  // 一次请求,随处使用

效果拔群!堪称 Firebase 好搭档!

然后......React 19 发布了,他的项目炸了!💥

为什么?因为他发现了这段让人瞳孔地震的代码:

javascript 复制代码
const ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// 注意:这是危险操作,请勿模仿!

好家伙!作者直接用了 React 的私密接口,现在 React 19 删了这接口,库就原地爆炸了!

于是我基友只能含泪回归 Redux,从"真香"变成"真伤"😭

技术揭秘:官方认证的解决方案 🔧

React 其实早就给了我们正经方案:useSyncExternalStore!

看这个炫酷的示例:

javascript 复制代码
let counter = 0;
let listeners = [];

const subscribe = (listener) => {
  listeners.push(listener);
  return () => listeners = listeners.filter(l => l !== listener);
};

const getSnapshot = () => counter;

const setCounter = (value) => {
  counter = value;
  listeners.forEach(listener => listener());
};

function CounterComponent() {
  const value = useSyncExternalStore(subscribe, getSnapshot);
  return <button onClick={() => setCounter(value + 1)}>{value}</button>;
}

这才是官方认证的优雅姿势!从此告别 hack,走向人生巅峰!

高级玩法:不是所有状态都要全球飞 🌏

有时候你只想在小圈子里共享状态?安排!

jsx 复制代码
<SharedStatesProvider>
  <YourComponent />
</SharedStatesProvider>

想来点更骚的操作?多个组件树共享同一状态?

jsx 复制代码
<SharedStatesProvider scopeName="modal">
  <ModalContent />
</SharedStatesProvider>

<Portal>
  <SharedStatesProvider scopeName="modal">
    <FloatingToolbar />
  </SharedStatesProvider>
</Portal>

即使在不同 React 树中,也能同步状态,就问你6不6!

异步操作:一键搞定数据请求 ⚡

jsx 复制代码
const fetchUser = () => fetch("/api/me").then(r => r.json());

function Profile() {
  const { state, trigger } = useSharedFunction("current-user", fetchUser);

  useEffect(() => { trigger(); }, []);

  if (state.isLoading && !state.results) return <p>Loading...</p>;
  if (state.error) return <p>Error!</p>;

  return <h1>{state.results.name}</h1>;
}

一次请求,全家享用!自动缓存+去重,性能优化直接拉满!

实时数据:Firebase/WebSocket 一键接入 🔥

jsx 复制代码
const { state, trigger } = useSharedSubscription(
  "user-123",
  (update, onError, onComplete) => {
    const unsubscribe = firebase.onSnapshot(doc(db, "users", "123"), (snapshot) => {
      update(snapshot.data());
    }, onError, onComplete);
    return unsubscribe;
  }
);

第一个组件建立连接,其他组件白嫖数据!用完自动断开,绝不内存泄漏!

彩蛋功能:在 React 外部操控状态 🎁

javascript 复制代码
import { sharedStatesApi } from "react-shared-states";

sharedStatesApi.set("theme", "dark");  // 随时随地修改状态
console.log(sharedStatesApi.get("theme"));

SSR、调试、非 React 代码都能用,就问你贴不贴心!

总结时刻 🎉

  • 我基友用了 useBetween → React 19 发布 → 项目爆炸 → 含泪回归 Redux
  • 我灵机一动 → 用 useSyncExternalStore 重写 → react-shared-states 诞生!
  • 现在你可以:共享状态、作用域隔离、异步操作、实时订阅、外部API...要啥有啥!

如果你也:

  • 受够了 Context 的层层包裹
  • 不想再写 Redux 的模板代码
  • 想要轻量又强大的状态管理

那么......还不快去给个 Star!⭐️

GitHub 传送门:react-shared-states

因为说真的......React 状态管理从未如此简单,如此有趣!🚀

(小声说:用了这个,你可能就再也回不去了......)

相关推荐
7ayl12 分钟前
Vue3 - Reactivity的核心流程
前端·vue.js
The 旺13 分钟前
【AI编程实战】零基础用ChatGPT+Cursor开发完整Web应用:30分钟从idea到上线
前端·chatgpt·ai编程
sulikey24 分钟前
Qt 入门简洁笔记:信号与槽
前端·c++·笔记·qt·前端框架·1024程序员节·qt框架
袁煦丞28 分钟前
安卓旧机变服务器,KSWEB部署Typecho博客并实现远程访问:cpolar内网穿透实验室第645个成功挑战
前端·程序员·远程工作
爱抽烟的大liu29 分钟前
iOS进阶1-combine
前端
俩毛豆30 分钟前
【图片】【编缉】图片增加水印(通过组件的Overlay方法增加水印)
前端·harmonyos
gustt31 分钟前
JS 变量那些坑:从 var 到 let/const 的终极解密
前端·javascript
出师未捷的小白31 分钟前
[NestJS] 手摸手~工作队列模式的邮件模块解析以及grpc调用
前端·后端
Z_B_L1 小时前
问题记录--elementui中el-form初始化表单resetFields()方法使用时出现的问题
前端·javascript·vue.js·elementui·1024程序员节
袁煦丞1 小时前
PandaWiki开源知识库系统破解内网限制:cpolar内网穿透实验室第616个成功挑战
前端·程序员·远程工作