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);
//  其實是對間接引用(dereference)值的反應,值須要經過引用來傳遞而不是經過(字面量)值來傳遞。
// React.render(<Timer timerData={timerData.secondsPassed} />, document.body) 將不會改變@observer
// 使用 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 調用後會觸發此鉤子
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息