天天看點

react全局狀态管理_react狀态管理redux{value}

Redux(上)

結合阮老師的技術部落格,将自己吸收到的内容做了個整理:

曾經有人說過這樣一句hua : 如果你不知道是否需要Redux,那就是不需要它。

從組建層面考慮,什麼樣子的需要redux;某個元件的狀态需要共享,

某個狀态需要在任何地方都可以拿到,

一個元件需要改變全局狀态,

一個元件需要改變另一個元件的狀态

一)Redux的設計思想 很重要

1)web應用是一個狀态機,試圖與狀态是一一對應的

2)所有的狀态,儲存在一個對象裡面(唯一資料源)

二)基本概念和 API

1、store

store就是儲存資料的地方,你可以把它看成一個容器。整個應用隻能有一個Store

Redux提供createStore這個函數,用來生成Store,import {createStore} from 'redux'

/建立一個reducer檔案夾 并引入reducer

const store = createStore(reducer)

export default store

2、state

Store對象包含所有資料。如果想得到某個時點的資料,就要對 Store 生成快照。這種時點的資料集合,就叫做 State。

目前時刻的 State,可以通過store.getState()拿到。import { createStore } from 'redux';

const store = createStore(fn);

const state = store.getState();

Redux 規定, 一個 State 對應一個 View。隻要 State 相同,View 就相同。你知道 State,就知道 View 是什麼樣,反之亦然。

3、Action

State 的變化,會導緻 View 的變化。但是,使用者接觸不到 State,隻能接觸到 View。是以,State 的變化必須是 View 導緻的。Action 就是 View 發出的通知,表示 State 應該要發生變化了。

Action 是一個對象。其中的type屬性是必須的,表示 Action 的名稱。其他屬性可以自由設定,社群有一個規範可以參考。const action = {

type: 'ADD_TODO',

payload: 'Learn Redux'

};

上面代碼中,Action 的名稱是ADD_TODO,它攜帶的資訊是字元串Learn Redux。

可以這樣了解,Action 描述目前發生的事情。改變 State 的唯一辦法,就是使用 Action。它會運送資料到 Store。

4、Action Creator

View 要發送多少種消息,就會有多少種 Action。如果都手寫,會很麻煩。可以定義一個函數來生成 Action,這個函數就叫 Action Creator。const ADD_TODO = '添加 TODO';

function addTodo(text) {

return {

type: ADD_TODO,

text

}

}

const action = addTodo('Learn Redux');

上面代碼中,addTodo函數就是一個 Action Creator。

5、store.dispatch()

store.dispatch()是 View 發出 Action 的唯一方法。import { createStore } from 'redux';

const store = createStore(fn);

store.dispatch({

type: 'ADD_TODO',

payload: 'Learn Redux'

});

上面代碼中,store.dispatch接受一個 Action 對象作為參數,将它發送出去。

結合 Action Creator,這段代碼可以改寫如下。store.dispatch(addTodo('Learn Redux'));​

6、Reducer

Store 收到 Action 以後,必須給出一個新的 State,這樣 View 才會發生變化。這種 State 的計算過程就叫做 Reducer。

Reducer 是一個函數,它接受 Action 和目前 State 作為參數,傳回一個新的 State。const reducer = function (state, action) {

// ...

return new_state;

};

整個應用的初始狀态,可以作為 State 的預設值。下面是一個實際的例子。const defaultState = 0;

const reducer = (state = defaultState, action) => {

switch (action.type) {

case 'ADD':

return state + action.payload;

default:

return state;

}

};

const state = reducer(1, {

type: 'ADD',

payload: 2

});

上面代碼中,reducer函數收到名為ADD的 Action 以後,就傳回一個新的 State,作為加法的計算結果。其他運算的邏輯(比如減法),也可以根據 Action 的不同來實作。

實際應用中,Reducer 函數不用像上面這樣手動調用,store.dispatch方法會觸發 Reducer 的自動執行。為此,Store 需要知道 Reducer 函數,做法就是在生成 Store 的時候,将 Reducer 傳入createStore方法。import { createStore } from 'redux';

const store = createStore(reducer);

上面代碼中,createStore接受 Reducer 作為參數,生成一個新的 Store。以後每當store.dispatch發送過來一個新的 Action,就會自動調用 Reducer,得到新的 State。

7、store.subscribe()

Store 允許使用store.subscribe方法設定監聽函數,一旦 State 發生變化,就自動執行這個函數。import { createStore } from 'redux';

const store = createStore(reducer);

store.subscribe(listener);

顯然,隻要把 View 的更新函數(對于 React 項目,就是元件的render方法或setState方法)放入listen,就會實作 View 的自動渲染。

store.subscribe方法傳回一個函數,調用這個函數就可以解除監聽。let unsubscribe = store.subscribe(() =>

console.log(store.getState())

);

unsubscribe();​

三)舉個例子

簡單計數器的例子:麻雀雖小,五髒俱全

主要是觀察store中的三個方法:

1、store.getState(); 在視圖層通過該方法取到存儲在store中的state。下圖中23、24行代碼

2、store.dispatch(); 在視圖層通過該方法發送一個actions,去通知reducers去改變state值。下面的reducer函數

3、store.subscribe(); 通過該函數設定監聽,一旦state發生改變,就會調用該函數,重新渲染視圖層,如下面的31行代碼

很明顯 redux中 reducer和Action Creators都是一個純函數,這就要求他們不允許:直接修改 state 參數對象

請求 API

調用不純的函數,比如 Data.now() Math.random()

那這樣的話,異步操作是如何實作的呢,這就需要借助中間件redux-thunk或者redux-sage在發出action到reducer接收到action之間來執行異步操作。(redux-thunk、redux-sage介紹參考簡書)const Counter = ({ value, onIncrement, onDecrement }) => (

{value}

+

-

);

const reducer = (state = 0, action) => {

switch (action.type) {

case 'INCREMENT': return state + 1;

case 'DECREMENT': return state - 1;

default: return state;

}

};

const store = createStore(reducer);

const render = () => {

ReactDOM.render(

value={store.getState()}

onIncrement={() => store.dispatch({type: 'INCREMENT'})}

onDecrement={() => store.dispatch({type: 'DECREMENT'})}

/>,

document.getElementById('root')

);

};

render();

store.subscribe(render);