restate / v1.0.0

快速开始

安装 restate,在组件之间共享第一个值,并在 React 之外使用同一个 store。

本页内容安装你的第一个共享状态更新值在 React 之外使用TypeScriptReact Native所有平台,同一个声明

安装

restate 支持 React 16.8 及以上版本,自带 TypeScript 类型声明,没有其他运行时依赖。

Terminal
npm install @kkwaenggwari/restate

你的第一个共享状态

在组件外部创建一次 store。restate 返回的值既是 Hook,也是带有 set、get 等方法的对象。

Editor 和 CharacterCount 之间没有 props,也没有 Provider。在一个里输入,另一个就会更新。

JavaScript / JSX
import { restate } from '@kkwaenggwari/restate';

export const useDraft = restate('');

export function Editor() {
  const text = useDraft();
  return <textarea value={text} onChange={(event) => useDraft.set(event.target.value)} />;
}

export function CharacterCount() {
  const count = useDraft((text) => text.length);
  return <span>{count} characters</span>;
}

更新值

set 接受一个新值,或一个基于旧值计算的函数。reset 回到你声明的初始值。

把值当作不可变数据:返回新的对象或数组,而不是修改旧的,这样 selector 才能察觉到变化。

你往 cart.items 里 push,再调用 useCart.set(cart)。为什么什么都没有重新渲染?

store 收到的是同一个对象,Object.is 判断没有变化。请返回一个新对象,例如 useCart.set(cart => ({ ...cart, items: [...cart.items, item] }))。

JavaScript / JSX
useCount.set(10); // replace the value
useCount.set((count) => count + 1); // compute from the previous value
useCount.reset(); // back to the declared initial value

在 React 之外使用

同一个 store 也能用在事件处理函数、服务和测试中。get 读取当前值;subscribe 在每次变化后调用你,并返回一个停止监听的函数。

JavaScript / JSX
import { useCart } from './stores/cart';

// Any module, event handler or test can use the same store.
const current = useCart.get();
useCart.set((cart) => ({ ...cart, items: [...cart.items, 'Pen'] }));

const stop = useCart.subscribe((cart, previous) => {
  console.log(previous.items.length, '→', cart.items.length);
});
stop();

TypeScript

只需传一次状态类型,selector、set 和所有方法都会据此得到类型。

JavaScript / JSX
import { restate } from '@kkwaenggwari/restate';

type Cart = { items: string[]; coupon: string };

export const useCart = restate<Cart>({ items: [], coupon: '' });

const count = useCart((cart) => cart.items.length); // number
useCart.set((cart) => ({ ...cart, coupon: 'SPRING' }));

React Native

在 React Native 上,内存 store 不需要任何额外配置。要保存状态,请安装 react-native-mmkv,React Native 入口会自动加载它。

对于 bare 项目,安装后请为 iOS 执行 pod install。在 Expo 中,由于 MMKV 是原生模块,请使用 development build。

Terminal
npm install @kkwaenggwari/restate react-native-mmkv@4 react-native-nitro-modules

所有平台,同一个声明

持久化 store 在浏览器中使用 IndexedDB,在 React Native 上使用 MMKV。声明和组件都保持不变。

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

// IndexedDB on the web, MMKV on React Native. Same declaration.
export const useDraft = persistedRestate('', { key: 'draft' });

搜索文档

搜索所有指南的标题、描述和正文。