redux
react中狀態(tài)管理工具遏插,用來管理應(yīng)用中的數(shù)據(jù)调煎。
核心
Action:行為的抽象,視圖中的每個(gè)用戶交互都是一個(gè)action纳寂。比如:點(diǎn)擊按鈕主穗。
Reducer:行為響應(yīng)的抽象,也就是:根據(jù)action行為毙芜,執(zhí)行相應(yīng)的邏輯操作忽媒,更新state。比如:點(diǎn)擊按鈕后腋粥,添加任務(wù)猾浦,那么,添加任務(wù)這個(gè)邏輯放到Reducer中灯抛;創(chuàng)建State金赦。
Store:1.Redux應(yīng)用只能有一個(gè)store;2.getState() 獲取state对嚼;3.diapatch(action) 更新state夹抗。
在Redux中,所有的數(shù)據(jù)(比如state)被保存在一個(gè)被稱為store的容器中纵竖,在一個(gè)應(yīng)用程序中只能有一個(gè)漠烧。store本質(zhì)上是一個(gè)狀態(tài)樹,保存了所有對象的狀態(tài)靡砌。任何UI組件都可以直接從store訪問特定對象的狀態(tài)已脓。要通過本地或遠(yuǎn)程組件更改狀態(tài),需要分發(fā)一個(gè)action通殃。分發(fā)在這里意味著將可執(zhí)行信息發(fā)送到store度液。當(dāng)一個(gè)store接收到一個(gè)action,它將把這個(gè)action代理給相關(guān)的reducer画舌。reducer是一個(gè)純函數(shù)堕担,它可以查看之前的狀態(tài),執(zhí)行一個(gè)action并且返回一個(gè)新的狀態(tài)曲聂。
/* action */
// 在 redux 中霹购,action 就是一個(gè)對象
// action 必須提供一個(gè):type屬性,表示當(dāng)前動(dòng)作的標(biāo)識
// 其他的參數(shù):表示這個(gè)動(dòng)作需要用到的一些數(shù)據(jù)
{ type: 'ADD_TODO', name: '要添加的任務(wù)名稱' }
// 這個(gè)動(dòng)作表示要切換任務(wù)狀態(tài)
{ type: 'TOGGLE_TODO', id: 1 }
/* reducer */
// 第一個(gè)參數(shù):表示狀態(tài)(數(shù)據(jù))朋腋,我們需要給初始狀態(tài)設(shè)置默認(rèn)值
// 第二個(gè)參數(shù):表示 action 行為
function todo(state = [], action) {
switch(action.type) {
case 'ADD_TODO':
state.push({ id: Math.random(), name: action.name, completed: false })
return state
case 'TOGGLE_TODO':
for(var i = 0; i < state.length; i++) {
if (state[i].id === action.id) {
state[i].completed = !state[i].completed
break
}
}
return state
default:
return state
}
}
// 要執(zhí)行 ADD_TODO 這個(gè)動(dòng)作:
dispatch( { type: 'ADD_TODO', name: '要添加的任務(wù)名稱' } )
// 內(nèi)部會調(diào)用 reducer
todo(undefined, { type: 'ADD_TODO', name: '要添加的任務(wù)名稱' })
一個(gè)例子:
import { createStore } from "redux";
import { combineReducers } from 'redux';
const productsReducer = function(state=[], action) {
return state;
}
const initialState = {
cart: [
{
product: 'bread 700g',
quantity: 2,
unitCost: 90
},
{
product: 'milk 500ml',
quantity: 1,
unitCost: 47
}
]
}
const ADD_TO_CART = 'ADD_TO_CART';
const cartReducer = function(state=initialState, action) {
switch (action.type) {
case ADD_TO_CART: {
return {
...state,
cart: [...state.cart, action.payload]
}
}
default:
return state;
}
}
function addToCart(product, quantity, unitCost) {
return {
type: ADD_TO_CART,
payload: {
product,
quantity,
unitCost
}
}
}
const allReducers = {
products: productsReducer,
shoppingCart: cartReducer
}
const rootReducer = combineReducers(allReducers);
let store = createStore(rootReducer);
console.log("initial state: ", store.getState());
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
store.dispatch(addToCart('Coffee 500gm', 1, 250));
store.dispatch(addToCart('Flour 1kg', 2, 110));
store.dispatch(addToCart('Juice 2L', 1, 250));
unsubscribe();