簡介
Redux是一個非常有用的框架,他主要解決狀態的統一管理問題。而React則將所有組件視爲狀態機,所以Redux可以看作是一個React的數據管理中心。但需要注意,並不是必須用Redux來管理數據,只是該框架讓複雜業務邏輯和多組件通信更加方便。
Redux的思想主要概括爲下面2點:
a.Web 應用是一個狀態機,視圖與狀態是一一對應的。
b.所有的狀態,保存在一個store對象裏面。
這樣state就是一個單一的對象,所有的狀態數據都維護在一顆狀態樹中,服務端很容易初始化狀態,state則只能通過dispath(action)來觸發更新,更新邏輯由reducer執行。
概念說明
Store
store是一個存儲對象,保存着所有的數據,整個應用只有唯一一個Store對象。
Redux提供了createStore(fn)來生成一個Store對象
import { createStore } from 'redux';
const store = createStore(fn);
store.getState():獲取當前狀態
store.dispatch(action):用於觸發state更新,將action發出。
store.subscribe(lister):用於註冊state變化監聽器,返回一個函數,調用該函數則解除監聽器。
createStore(reducer,[initalState]):創建Store對象
State
Store對象包含所有數據,如果想得到某個時點的數據,就需要對Store生成快照,而生成的快照數據集合就叫做State。當前時刻的State可以通過store.getState()得到。
import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();
Action
狀態的改變將會導致視圖的變化,但是用戶只能操作視圖,所以必須讓視圖的操作來影響狀態的改變,Action的作用就是通知視圖操作了,狀態也應該做相應的改變來渲染視圖操作的效果。
Action是一個對象,該對象有如下屬性:
type:action的名稱,通常是字符串常量或者符號,必須。
payload:攜帶的信息,任何類型的值,可選。如果error爲true則payload是一個錯誤對象。
error:操作錯誤標識,任何類型的值,可選。
meta:payload外的其他信息,任何類型的值,可選。
const actionName = "Redux test";
function addAction(text){
return {
type:actionName,
payload:text
}
}
const newAction = addAction("Learn Redux");
Reducer
Store接收到Action以後,必須返回一個新的State,這樣視圖纔會重新渲染,計算新的State的過程叫做Reducer。
Reducer是一個函數,接受2個參數,當前的state和action,返回一個新的state。
const reducer = function (state, action) {
// ...
return new_state;
};
redux的工作原理:
1.首先定義好組件;
2.在組件觸發事件中調用stroe.dispatch(action),發出action,自動執行Reducer函數;
3.定義好Reducer對象來處理組件發出的action;
4.根據定義的Reducer對象創建store對象;
5.創建監聽器,在store改變後重新渲染界面。store.subscribe(lister)
簡易流程
component --> dispatch(action) --> reducer --> subscribe --> getState --> component
示例
import {createStore} from 'redux';
import React from 'react';
import ReactDOM from 'react-dom';
let countReducer = (state=0,action) => {//第二步:定義Reducer執行函數
switch(action.type){
case "add":
state += 1;
break;
case "substrat":
state -= 1;
break;
default:
break
}
return state;
}
let store = createStore(countReducer);//第三步:創建Store對象
let addCount = ()=>{//加法操作
store.dispatch({
type:"add",
payload:"每次加1"
})
}
let subStractCount= () => {//減法操作
store.dispatch({
type:"substrat",
payload:"每次減1"
})
}
const render = () => {
ReactDOM.render(//第一步:定義組件,getState()本爲第五步,這裏未做區分
<div>
<h1>{store.getState()}</h1>
<button onClick={addCount} style={{padding:"5px 15px",margin:"0 10px 0 0"}}>+</button>
<button onClick={subStractCount} style={{padding:"5px 15px",margin:"0 10px 0 0"}}>-</button>
</div>,
document.getElementById("redux")
)
}
store.subscribe(render)//第四步:創建監聽器,監聽到狀態修改後就重新渲染界面
render()//初始化渲染
效果圖:
點擊+號,數字加1,點擊-號,數字減一。