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/