若是你不知道mobx是什麼,請閱讀這篇文章html
在這一篇文章裏,將展現一些使用了mobx的React的最佳實踐方式,並按照一條一條的規則來展現。在你遇到問題的時候,能夠依照着這些規則來解決。react
這篇文章要求你對於mobx的stores有基本的理解,若是沒有的話請先閱讀官方文檔。git
永遠記住,你的stores表明着你的UI狀態,這就意味着,當你將你的stores儲存下來後,就算你關了網頁,再次打開,載入這個stores,你獲得的網頁也應該是相同的。雖然stores並非一個本地數據庫的角色,可是他依然存儲着一些相似於按鈕是否可見,input裏面的內容之類的UI狀態。github
class SearchStore {
@observable searchText;
@action
setSearchText = (searchText) => {
this.searchText = searchText
}
}
@observer
class SearchInput extends React.Component {
handleInputChanged = (event) => {
const { searchStore } = this.props;
searchStore.setSearchText(event.target.value);
}
render() {
const { searchStore } = this.props;
return (
<input value={searchStore.searchText} onChange={this.handleInputChanged} /> ); } } 複製代碼
不建議將REST API請求的函數放在stores裏面,由於這樣以來這些請求代碼很難測試。你能夠嘗試把這些請求函數放在一個類裏面,把這個類的代碼和store放在一塊兒,在store建立時,這個類也相應建立。而後當你測試時,你也能夠優雅的把數據從這些類裏面mock上去。數據庫
class TodoApi {
fetchTodos = () => request.get('/todos')
}
class TodoStore {
@observable todos = [];
constructor(todoApi) {
this.todoApi = todoApi;
}
fetchTodos = async () => {
const todos = await this.todoApi.fetchTodos();
runInAction(() => {
this.todos = todos;
});
}
}
// 在你的主要函數裏面
const todoApi = new TodoApi();
const todoStore = new TodoStore(todoApi);
複製代碼
儘可能不要把業務邏輯寫在你的組件裏面。當你把業務邏輯寫在組件裏面的時候,你是沒有辦法來及時定位錯誤的,由於你的業務邏輯分散在各類不一樣的組件裏面,讓你很難來經過行爲來定義究竟是哪些代碼涉及的這個錯誤。最好就把業務邏輯放在stores的方法裏面,從組件裏面調用。bash
請儘可能避免使用全局的store實例,由於這樣你很難寫出有條理而可靠的組件測試。取而代之的是,你可使用Provider來把你的store inject到你的component實例的props裏面。這樣你就能夠輕鬆的mock這些store來測試了。app
const searchStore = new SearchStore();
const app = (
<Provider searchStore={searchStore}> <SearchInput /> </Provider>
);
ReactDom.render(app, container);
複製代碼
mobxjs/mobx-reactasync
請不要直接在組件裏面直接操做store的屬性值。由於只有store纔可以來修改本身的屬性。當你要改變屬性的時候,請使用相應的store方法。否則的話你的屬性修改會散落在各處不受控制,這是很難debug的。ide
@observer
在每一個組件聲明的時候使用@observer來更新組件的狀態。否則在嵌套組件裏面,子組件沒有聲明的話,每次狀態更新涉及到的都是父組件級的從新渲染。當你都使用了@observer
時,從新渲染的組件數量會大大下降。函數
@computed
就像下面代碼的例子,使用@computed
屬性來處理一些涉及多個屬性的邏輯。使用@computed
能夠減小這樣的判斷類業務邏輯在組件裏面出現的頻率。
class ApplicationStore {
@observable loggedInUser;
@observable isInAdminMode;
@computed isAdminButtonEnabled = () => {
return this.loggedInUser.role === 'admin' && this.isInAdminMode;
}
}
複製代碼
你不須要使用react router管理狀態。就像我前面所說的,你的store就表明了應用的狀態。當你讓router來管理部份應用狀態的時候,這部分狀態就從store裏面剝離開來。因此儘可能使用store來儲存全部的UI狀態,這樣store的屬性就是你的界面所得。
多編寫可控組件,這樣會大大下降你的測試複雜度,也讓你的組件易於管理。
原文:Mobx React — Best Practices
翻譯:Dominic Ming