echo-state
用同一种状态模型处理内存、持久化与跨窗口同步。
状态的差别,不只在于它存了什么,也在于它应该活多久、在哪里保持一致。
React 组件中的状态可以只存在几秒,也可能需要在页面刷新后继续存在,或在多个浏览器标签页之间保持同步。很多项目分别使用组件状态、LocalStorage、IndexedDB 和额外的同步逻辑处理这些情况,结果是同一个业务状态拥有多套读取、写入和初始化方式。
echo-state 是我为这类重复问题编写的轻量状态库。它用同一个 Echo 实例描述状态,再根据实际生命周期选择临时存储、LocalStorage 或 IndexedDB。
状态应该拥有明确的生命周期
临时界面状态不需要落盘;用户偏好需要在刷新后保留;较大或结构化的数据更适合 IndexedDB;多个窗口同时操作同一份状态时,还需要传播变化。
echo-state 将这些选择作为状态本身的配置,而不是散落在组件副作用中。组件通过同一套 Hooks API 使用状态,存储方式可以随着需求改变,而不需要重新设计业务层的访问方式。
import { Echo } from "echo-state";
const user_store = new Echo({
name: "",
is_logged_in: false,
});
const state = user_store.use();
user_store.set({ name: "Wangenius" });
只订阅真正关心的部分
当一个 Store 包含多个字段时,组件通常只依赖其中一部分。echo-state 支持通过 Selector 订阅局部状态,使不相关的变化不必触发组件更新。
const user_name = user_store.use((state) => state.name);
持久化状态还可以通过 ready() 等待初始化完成,避免应用在存储尚未载入时读取错误的默认值。跨窗口同步则让多个标签页共享最新变化,而不需要每个产品再次实现通信层。
一个来自实际产品开发的基础模块
我在开发桌面工具、文档工作区和 Agent 产品时,反复遇到设置、会话、编辑状态与本地数据采用不同生命周期的问题。echo-state 将其中稳定、可复用的部分抽取为独立库:保持 API 小,使用 TypeScript 提供完整类型,并且不引入外部运行时依赖。
它不是一套试图管理所有应用架构的框架,而是一个边界清楚的状态原语:创建状态、更新状态、订阅所需部分,并明确决定它如何被保存和同步。