react-mobx-3


Flow

用法: flow(function* (args) { })

// 包装异步函数。这将确保所有回调都会被 action() 包装。
// flow() 接收 generator 函数作为它唯一的输入
// flow 会返回一个 promise ,需要的话可以使用 cancel() 进行撤销。

import { configure } from 'mobx';

// 不允许在动作外部修改状态
configure({ enforceActions: true });

class Store {
    @observable githubProjects = [];
    @observable state = "pending"; // "pending" / "done" / "error"


    fetchProjects = flow(function* fetchProjects() { // <- 注意*号,这是生成器函数!
        this.githubProjects = [];
        this.state = "pending";
        try {
            const projects = yield fetchGithubProjectsSomehow(); // 用 yield 代替 await
            const filteredProjects = somePreprocessing(projects);

            // 异步代码自动会被 `action` 包装
            this.state = "done";
            this.githubProjects = filteredProjects;
        } catch (error) {
            this.state = "error";
        }
    })
}
// Flows 是可以取消的,调用返回的 promise 的 cancel() 方法。
// 会立即停止 generator ,但是 finally 子句仍会被处理。 
// 返回的 promise 本身会使用 FLOW_CANCELLED 进行 reject 
 
 
// Flows 支持异步迭代器

async function* someNumbers() {
    yield Promise.resolve(1)
    yield Promise.resolve(2)
    yield Promise.resolve(3)
}

const count = mobx.flow(async function*() {
    // 使用 await 来循环异步迭代器
    for await (const number of someNumbers()) {
        total += number
    }
    return total
})

const res = await count() // 6

 

Reactions(反应) & Derivations(衍生)

observer
// observer 函数/装饰器可以用来将 React 组件转变成响应式组件
// 它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。 
// observer 是由单独的 mobx-react 包提供的。

import {observer} from "mobx-react";

var timerData = observable({
    secondsPassed: 0
});

setInterval(() => {
    timerData.secondsPassed++;
}, 1000);

@observer class Timer extends React.Component {
    render() {
        return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
    }
};

ReactDOM.render(<Timer timerData={timerData} />, document.body);
// @observer 实际上是对间接引用(dereference)值的反应,值需要通过引用来传递而不是通过(字面量)值来传递。
// React.render(<Timer timerData={timerData.secondsPassed} />, document.body) 将不会改变
// 使用 inject 将组件连接到提供的 stores
// 传递stores名称列表给 inject,这使得 stores 可以作为组件的 props 使用
// 应该一直使用 inject(stores)(component) 或 @inject(stores) class Component...。 
// 直接传递 store 名称给 observer 的方式已废弃。

const colors = observable({
   foreground: '#000',
   background: '#fff'
});

const App = () =>
  <Provider colors={colors}>
     <app stuff... />
  </Provider>;

const Button = inject("colors")(observer(({ colors, label, onClick }) =>
  <button style={{
      color: colors.foreground,
      backgroundColor: colors.background
    }}
    onClick={onClick}
  >{label}</button>
));

// 稍后..
colors.foreground = 'blue';
// 所有button都会更新
componentWillReact (生命周期钩子)

// React 组件通常在新的堆栈上渲染,这使得通常很难弄清楚是什么导致组件的重新渲染
// 当组件观察的数据发生了改变,会重新渲染,componentWillReact 会被触发。这使得它很容易追溯渲染并找到导致渲染的操作(action)。

import {observer} from "mobx-react";

@observer class TodoView extends React.Component {
    componentWillReact() {
        console.log("I will re-render, since the todo has changed!");
    }

    render() {
        return <div>this.props.todo.title</div>;
    }
}

1, componentWillReact 不接收参数
2, componentWillReact 初始化渲染前不会触发 (使用 componentWillMount 替代)
3, componentWillReact 对于 mobx-react@4+, 当接收新的 props 时并在 setState 调用后会触发此钩子

猜你喜欢

转载自www.cnblogs.com/avidya/p/11738053.html