MobX
使用MobX 存储应用状态
严格来说,
MobX 的基础使用
测试
class MessageStore {
// bad
markMessageAsRead = (message) => {
if (message.status === "new") {
fetch({
method: "GET",
path: `/notification/read/${message.id}`,
}).then(() => (message.status = "read"));
}
};
// good
markMessageAsRead = (message) => {
if (message.status !== "new") {
return Promise.reject("Message is not new");
}
// it's now easily mockable
return api.markMessageAsRead(message).then(() => {
// this is a pure function
// you can test it easily
return this.updateMessage(message, { status: " read" });
});
};
}
MobX 与React 集成范式
MST
MobX 的设计理念
MobX 与Redux 的对比
本文的最后,我们也讨论下
First of all, state within Redux is simply represented as plain objects. Nothing more. Redux makes state tangible. You can pick up objects and drop them in a different place. Like in local storage or in the body of a network request.
Secondly, Redux offers many constraints that make it easy to write generic algorithms that reason about the state without specific domain knowledge (unlike reducers). Such algorithms are typically expressed as middleware. Creating such mechanisms is feasible, partly because the data is immutable, but mostly because the state is tree shaped and preferably serializable. This makes it possible to traverse any Redux state tree in a predictable manner.
await this.props.actions.choose({
workShiftIdList: _.map(items, (d) => d.workShiftId),
});
this.trace("batch-chose", { size: items.length });
await this.fetchTableData();
actions.chooseWorks = (works) => (dispatch) => {
choose(works).then(
() => {
// 更新结果信息
dispatch(createAction(CHOOSE_WORKS));
// 执行重新抓取操作
dispatch(actions.fetchChoices());
// 清空已选
dispatch({
type: `${prefix}/CLEAR_SELECTED_WORKs`,
});
},
() => {}
);
};
WebSocket
import { onBecomeObserved, onBecomeUnobserved } from "mobx";
import { observable, decorate } from "mobx";
class AutoObservable<T> {
data: T;
constructor(onObserved: () => void, onUnobserved: () => void) {
onBecomeObserved(this, "data", onObserved);
onBecomeUnobserved(this, "data", onUnobserved);
}
}
decorate(AutoObservable, {
data: observable,
});
let autoObservable: AutoObservable<number>;
let socket: Websocket;
const openStream = () => {
socket = new Websocket("ws://localhost:8080");
socket.on("message", (message) => {
autoObservable.data = message;
});
};
const closeStream = () => {
socket.close();
};
autoObservable = new AutoObservable(openStream, closeStream);