事件系统架构的类似 Redux 的状态管理方案

#1

Motivation

我真的很喜欢 redux 这种注重数据变化(action)的状态管理方案。但是有一些在我看来比较麻烦的地方。

Pure

首先我是很认可 pure 这个想法的,它有很多好处,方便测试和 debug。但是对我职业生涯来说,写出那么纯的代码往往不是一种荣誉而是一种负担。为了纯你得把一件事情拆分到2个文件去,写得多了觉得心累。所以我的方案里实现了一种不纯的 reducer。借用异步函数,副作用同样能写的很漂亮。

它看起来是这样的:

.match(Message, async () => this.setState({}))

给大家提供另一种写带有辅佐用的 reducer 的体验。

Dialog Problem

假设你有2个页面 pageA 和 pageB。pageA 下面有个 Dialog 组件 和一个 Button 按钮。页面切换到 pageB 之后 Dialog 销毁了。通过 Button 按钮触发 Dialog 的开关。

你要怎么设计你的 Dialog 状态呢?

熟练使用 Redux 的同学都知道 react 有2种状态:全局状态和本地状态。而 Redux 只能管理全局状态。也就是说一旦你把某个状态在项目初始化的时候写到 Redux Store 去了就没法销毁了。所以能不能有一种状态能全局还能动态销毁呢。

安装

npm i ractor

使用

这里有个 counter 的例子:https://codesandbox.io/s/olr841rqvz

1、 创建 ractor 系统

import { System } from "ractor";

export const system = new System("counter");

2、 定义消息

export class Increment {}

3、 创建 Store

import { Increment } from "./Increment";
import { Decrement } from "./Decrement";
import { Store } from "ractor";

export class CounterStore extends Store<{ value: number }> {
  public state = { value: 1 };

  public createReceive() {
    return this.receiveBuilder()
      .match(Increment, async () => this.setState({ value: this.state.value + 1 }))
      .build();
  }
}

3、 把 system 和 stores 和 react 绑定

import * as React from "react";
import { render } from "react-dom";
import { Provider } from "ractor-react";
import { system } from "./system";
import { CounterStore } from "./CounterStore";
import { Counter } from "./Counter";

render(
  <Provider system={system} stores={[CounterStore]}>
    <Counter />
  </Provider>,
  document.getElementById("root")
);

4、连接业务组件和 CounterStore

import * as React from "react";
import { Providers } from "ractor-react";
import { CounterStore } from "./CounterStore";
import { system } from "./system";
import { Increment } from "./Increment";
import { Decrement } from "./Decrement";

@Providers([CounterStore])
export class Counter extends React.Component<{ value?: number }> {
  public render() {
    return (
      <p>
        Clicked: {this.props.value} times{" "}
        <button onClick={() => system.dispatch(new Increment())}>+</button>{" "}
        <button onClick={() => system.dispatch(new Decrement())}>-</button>{" "}
      </p>
    );
  }
}

5、往系统里广播消息

system.dispatch(new Increment())

其他

项目地址:https://github.com/huangbinjie/ractor
项目文档:https://corol.gitbooks.io/ractor/content/

1 Like