Store

2018-02-24 15:28 更新

Store

Store 就是用來維持應(yīng)用所有的 state 樹 的一個對象。
改變 store 內(nèi) state 的惟一途徑是對它 dispatch 一個 action。

Store 不是類。它只是有幾個方法的對象。
要創(chuàng)建它,只需要把根部的 reducing 函數(shù) 傳遞給 createStore。

Flux 用戶使用注意

如果你以前使用 Flux,那么你只需要注意一個重要的區(qū)別。Redux 沒有 Dispatcher 且不支持多個 store。相反,只有一個單一的 store 和一個根級的 reduce 函數(shù)(reducer)。隨著應(yīng)用不斷變大,你應(yīng)該把根級的 reducer 拆成多個小的 reducers,分別獨(dú)立地操作 state 樹的不同部分,而不是添加新的 stores。這就像一個 React 應(yīng)用只有一個根級的組件,這個根組件又由很多小組件構(gòu)成。

Store 方法

Store 方法

getState()

返回應(yīng)用當(dāng)前的 state 樹。
它與 store 的最后一個 reducer 返回值相同。

返回值

(any): 應(yīng)用當(dāng)前的 state 樹。

dispatch(action)

分發(fā) action。這是觸發(fā) state 變化的惟一途徑。

會使用當(dāng)前 getState() 的結(jié)果和傳入的 action 以同步方式的調(diào)用 store 的 reduce 函數(shù)。返回值會被作為下一個 state。從現(xiàn)在開始,這就成為了 getState() 的返回值,同時變化監(jiān)聽器(change listener)會被觸發(fā)。

Flux 用戶使用注意

當(dāng)你在 reducer 內(nèi)部調(diào)用 dispatch 時,將會拋出錯誤提示“Reducers may not dispatch actions.(Reducer 內(nèi)不能 dispatch action)”。這就相當(dāng)于 Flux 里的 “Cannot dispatch in a middle of dispatch(dispatch 過程中不能再 dispatch)”,但并不會引起對應(yīng)的錯誤。在 Flux 里,當(dāng) Store 處理 action 和觸發(fā) update 事件時,dispatch 是禁止的。這個限制并不好,因?yàn)樗拗屏瞬荒茉谏芷诨卣{(diào)里 dispatch action,還有其它一些本來很正常的地方。

在 Redux 里,只會在根 reducer 返回新 state 結(jié)束后再會調(diào)用事件監(jiān)聽器,因此,你可以在事件監(jiān)聽器里再做 dispatch。惟一使你不能在 reducer 中途 dispatch 的原因是要確保 reducer 沒有副作用。如果 action 處理會產(chǎn)生副作用,正確的做法是使用異步 action 創(chuàng)建函數(shù)。

參數(shù)

  1. action (Object?): 描述應(yīng)用變化的普通對象。Action 是把數(shù)據(jù)傳入 store 的惟一途徑,所以任何數(shù)據(jù),無論來自 UI 事件,網(wǎng)絡(luò)回調(diào)或者是其它資源如 WebSockets,最終都應(yīng)該以 action 的形式被 dispatch。按照約定,action 具有 type 字段來表示它的類型。type 也可被定義為常量或者是從其它模塊引入。最好使用字符串,而不是 Symbols 作為 action,因?yàn)樽址强梢员恍蛄谢?。除?type 字段外,action 對象的結(jié)構(gòu)完全取決于你。參照 Flux 標(biāo)準(zhǔn) Action 獲取如何組織 action 的建議。

返回值

(Object?): 要 dispatch 的 action。

注意

? 使用 createStore 創(chuàng)建的 “純正” store 只支持普通對象類型的 action,而且會立即傳到 reducer 來執(zhí)行。

但是,如果你用 applyMiddleware 來套住 createStore 時,middleware 可以修改 action 的執(zhí)行,并支持執(zhí)行 dispatch intent(意圖)。Intent 一般是異步操作如 Promise、Observable 或者 Thunk。

Middleware 是由社區(qū)創(chuàng)建,并不會同 Redux 一起發(fā)行。你需要手動安裝 redux-thunk 或者 redux-promise 庫。你也可以創(chuàng)建自己的 middleware。

想學(xué)習(xí)如何描述異步 API 調(diào)用?看一下 action 創(chuàng)建函數(shù)里當(dāng)前的 state,執(zhí)行一個有副作用的操作,或者以鏈?zhǔn)讲僮鲌?zhí)行它們,參照 applyMiddleware 中的示例。

示例

import { createStore } from 'redux';
let store = createStore(todos, ['Use Redux']);

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  };
}

store.dispatch(addTodo('Read the docs'));
store.dispatch(addTodo('Read about the middleware'));

subscribe(listener)

添加一個變化監(jiān)聽器。每當(dāng) dispatch action 的時候就會執(zhí)行,state 樹中的一部分可能已經(jīng)變化。你可以在回調(diào)函數(shù)里調(diào)用 getState() 來拿到當(dāng)前 state。

這是一個底層 API。多數(shù)情況下,你不會直接使用它,會使用一些 React(或其它庫)的綁定。如果你想讓回調(diào)函數(shù)執(zhí)行的時候使用當(dāng)前的 state,你可以 把 store 轉(zhuǎn)換成一個 Observable 或者寫一個定制的 observeStore 工具

如果需要解綁這個變化監(jiān)聽器,執(zhí)行 subscribe 返回的函數(shù)即可。

參數(shù)

  1. listener (Function): 每當(dāng) dispatch action 的時候都會執(zhí)行的回調(diào)。state 樹中的一部分可能已經(jīng)變化。你可以在回調(diào)函數(shù)里調(diào)用 getState() 來拿到當(dāng)前 state。store 的 reducer 應(yīng)該是純函數(shù),因此你可能需要對 state 樹中的引用做深度比較來確定它的值是否有變化。
返回值

(Function): 一個可以解綁變化監(jiān)聽器的函數(shù)。

示例
function select(state) {
  return state.some.deep.property;
}

let currentValue;
function handleChange() {
  let previousValue = currentValue;
  currentValue = select(store.getState());

  if (previousValue !== currentValue) {
    console.log('Some deep nested property changed from', previousValue, 'to', currentValue);
  }
}

let unsubscribe = store.subscribe(handleChange);
handleChange();

replaceReducer(nextReducer)

替換 store 當(dāng)前用來計算 state 的 reducer。

這是一個高級 API。只有在你需要實(shí)現(xiàn)代碼分隔,而且需要立即加載一些 reducer 的時候才可能會用到它。在實(shí)現(xiàn) Redux 熱加載機(jī)制的時候也可能會用到。

參數(shù)

  1. reducer (Function) store 會使用的下一個 reducer。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號