Redux的基本使用過程步驟詳解
Redux的使用過程
Redux測試項目的搭建
1.創(chuàng)建一個新的項目文件夾:learn-redux
# 執(zhí)行初始化操作
npm init -y或yarn init -y# 安裝redux:
npm install redux --save或yarn add redux
2.創(chuàng)建src目錄,在src目錄下創(chuàng)建一個store文件夾, 并且在該文件夾下創(chuàng)建index.js文件
3.可以修改package.json用于執(zhí)行index.js, 也可以不配置, 直接使用node命令運行
"scripts": {
"start": "node src/index.js"
}Redux的基本使用步驟
1.創(chuàng)建一個對象,作為我們要保存的狀態(tài)state:
// 由于測試項目在node環(huán)境下, 因此使用require方式導(dǎo)入
const { createStore } = require("redux")
// 創(chuàng)建的要存儲的state: initialState
const initialState = {
name: "chenyq",
age: 18
}2.創(chuàng)建Store來存儲這個state
由于創(chuàng)建的state是不能直接放到創(chuàng)建的store中的, 需要通過reducer將數(shù)據(jù)添加到store中, 因此創(chuàng)建store時必須創(chuàng)建reducer;
reducer函數(shù)的返回值, 會作為store之后存儲的state
// 定義reducer, 將要存儲的state作為返回值返回
function reducer() {
return initialState
}
// 創(chuàng)建的store, 內(nèi)部會自動回調(diào)reducer, 拿到initialState
const store = createStore(reducer)
// 導(dǎo)出store
module.exports = store我們可以在其他文件中通過
store.getState來獲取當(dāng)前的state;
// 導(dǎo)入創(chuàng)建的store
const store = require("./store")
// 獲取store中的state
console.log(store.getState())
3.通過action來修改state
錯誤演示: 直接修改store
store.getState().name = "abc"
修改store中的數(shù)據(jù)不能直接修改, 必須要通過dispatch來派發(fā)action;
通常action中都會有type屬性,也可以攜帶其他的數(shù)據(jù);
// 定義一個action
const nameAction = { type: "change_name", name: "abc" }
// 派發(fā)action
store.dispatch(nameAction)當(dāng)然上面代碼中, 也可以寫為一行
// 派發(fā)action
store.dispatch({ type: "change_name", name: "abc" })4.修改reducer中的處理代碼
reducer接收兩個參數(shù):
參數(shù)一: store中當(dāng)前保存的state
參數(shù)二: 本次需要更新的action
只要調(diào)用dispatch就會重新執(zhí)行reducer函數(shù)
這里一定要記住,reducer是一個純函數(shù),不可以直接修改state, 后面我會講到直接修改state帶來的問題;
// 第一次state是undefined, 因此給一個默認值將初始化數(shù)據(jù)添加到store中
function reducer(state = initialState, action) {
// 有數(shù)據(jù)更新時, 返回一個新的state
if (action.type === "change_name") {
return { ...state, name: action.name }
}
// 沒有數(shù)據(jù)更新時, 返回之前的state
return state
}5.可以在派發(fā)action之前,監(jiān)聽store的變化:
通過
store.subscribe()函數(shù)可以監(jiān)聽store中的數(shù)據(jù)變化
store.subscribe()函數(shù)的參數(shù)接收一個函數(shù), 該函數(shù)在store數(shù)據(jù)發(fā)生更新自動回調(diào)
const store = require("./store")
// 例如: 監(jiān)聽數(shù)據(jù)的變化, 當(dāng)store變化, 就獲取最新的state
store.subscribe(() => {
console.log(store.getState())
})
store.dispatch({ type: "change_name", name: "abc" })
store.dispatch({ type: "change_name", name: "aaa" })6.封裝函數(shù)動態(tài)生成action
例如上面代碼中, 我們修改名稱多次, 只有傳入的action的name屬性值不相同, 那么我們可以封裝一個函數(shù), 動態(tài)的生成action, 這也是開發(fā)中一貫的做法
// 創(chuàng)建修改name的action
const changeNameAction = (name) => ({
type: "change_name",
name
})
// 創(chuàng)建修改age的action
const changeAgeAction = (num) => ({
type: "change_age",
num
})
// 在派發(fā)action時, 我們就可以調(diào)用函數(shù)即可獲取action
store.dispatch(changeNameAction("aaa"))
store.dispatch(changeNameAction("bbb"))
store.dispatch(changeNameAction("ccc"))
store.dispatch(changeAgeAction(10))
store.dispatch(changeAgeAction(20))
store.dispatch(changeAgeAction(30))
store.dispatch(changeAgeAction(40))Redux目錄的結(jié)構(gòu)劃分
如果我們將所有的邏輯代碼寫到一起,那么當(dāng)redux變得復(fù)雜時代碼就難以維護。
例如上面代碼中, 我們封裝的動態(tài)創(chuàng)建action的函數(shù), 這種動態(tài)生成action的函數(shù)在項目中可能會有很多個, 而且在其他多個文件中也可能會使用, 所以我們最好是有一個單獨的文件夾存放這些動態(tài)獲取action的函數(shù)
接下來,我會對代碼進行拆分,將store、reducer、action、constants拆分成一個個文件。
創(chuàng)建store/index.js文件: index文件中, 我們只需要創(chuàng)建store即可
const { createStore } = require("redux")
// 引入reducer
const reducer = require("./reducer")
// 創(chuàng)建的store, 內(nèi)部會自動回調(diào)reducer, 拿到initialState
const store = createStore(reducer)
// 導(dǎo)出store
module.exports = store創(chuàng)建store/reducer.js文件: 在真實項目中, reducer這個函數(shù)我們會越寫越復(fù)雜, 造成我們index.js文件越來越大, 所以我們將reducer也抽離到一個單獨的文件中
const { CHANGE_NAME, CHANGE_AGE } = require("./constants")
// 創(chuàng)建的要存儲的初始化state
const initialState = {
name: "chenyq",
age: 18
}
// 定義reducer, 將要存儲的state作為返回值返回
// 第一次state是undefined, 因此給一個默認值將初始化數(shù)據(jù)添加到store中
function reducer(state = initialState, action) {
switch(action.type) {
case CHANGE_NAME:
return { ...state, name: action.name }
case CHANGE_AGE:
return {...state, age: state.age + action.num}
}
// 沒有數(shù)據(jù)更新時, 返回之前的state
return state
}
module.exports = reducer創(chuàng)建store/constants.js文件: 將type的類型定義為常量(防止寫錯的情況), 這些常量最好也防止一個單獨的文件中
// store/constants.js
const CHANGE_NAME = "change_name"
const CHANGE_AGE = "change_age"
module.exports = {
CHANGE_NAME,
CHANGE_AGE
}創(chuàng)建store/actionCreators.js文件: 將封裝的動態(tài)創(chuàng)建action的函數(shù)放在該文件中, 在需要使用的地方導(dǎo)入即可
const { CHANGE_NAME, CHANGE_AGE } = require("./store/constants")
// 創(chuàng)建修改name的action
const changeNameAction = (name) => ({
type: CHANGE_NAME,
name
})
// 創(chuàng)建修改age的action
const changeAgeAction = (num) => ({
type: CHANGE_AGE,
num
})
module.exports = {
changeNameAction,
changeAgeAction
}最終形成如下目錄結(jié)構(gòu), 這也是官方推薦的目錄結(jié)構(gòu), 一個store中包含這四個文件夾

注意:node中對ES6模塊化的支持, 建議使用CommonJS規(guī)范
React的三大原則
單一數(shù)據(jù)源
整個應(yīng)用程序的state被存儲在一顆object tree中,并且這個object tree只存儲在一個 store 中:
Redux并沒有強制讓我們不能創(chuàng)建多個Store,但是那樣做并不利于數(shù)據(jù)的維護;
單一的數(shù)據(jù)源可以讓整個應(yīng)用程序的state變得方便維護、追蹤、修改;
State是只讀的
唯一修改State的方法一定是觸發(fā)action,不要試圖在其他地方通過任何的方式來修改State:
這樣就確保了View或網(wǎng)絡(luò)請求都不能直接修改state,它們只能通過action來描述自己想要如何修改state;
這樣可以保證所有的修改都被集中化處理,并且按照嚴格的順序來執(zhí)行,所以不需要擔(dān)心race condition(竟態(tài))的問題;
使用純函數(shù)來執(zhí)行修改
通過reducer將舊state和actions聯(lián)系在一起,并且返回一個新的State:
隨著應(yīng)用程序的復(fù)雜度增加,我們可以將reducer拆分成多個小的reducers,分別操作不同state tree的一部分;
但是所有的reducer都應(yīng)該是純函數(shù),不能產(chǎn)生任何的副作用;
到此這篇關(guān)于Redux的基本使用過程詳解的文章就介紹到這了,更多相關(guān)Redux基本使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
AJAX異步從優(yōu)酷專輯中采集所有視頻及信息(JavaScript代碼)
上次寫了一個 .NET從優(yōu)酷專輯中采集所有視頻及信息(VB.NET代碼)2010-11-11
javascript 動態(tài)修改css樣式方法匯總(四種方法)
為了達到某種特殊的效果我們需要用Javascript動態(tài)的去更改某一個標簽的Css屬性,如何動態(tài)修改css樣式呢?面對這個問題,小編帶領(lǐng)大家來解決javascript動態(tài)修改css樣式,小伙伴們都快來學(xué)習(xí)吧2015-08-08
微信小程序授權(quán)登陸及每次檢查是否授權(quán)實例代碼
這篇文章主要介紹了關(guān)于微信小程序授權(quán)登陸及每次檢查是否授權(quán),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09
詳解JS截取字符串的三個方法substring,substr,slice
js中有三個截取字符的方法,分別是substring()、substr()、slice(),平時我們可能都用到過,但總是會對這些方法有點混淆。本文將詳細介紹一下這三者的區(qū)別,需要的可以參考一下2022-03-03
利用jsonp跨域調(diào)用百度js實現(xiàn)搜索框智能提示
這篇文章主要為大家詳細介紹了使用jsonp跨域調(diào)用百度js實現(xiàn)搜索框智能提示,感興趣的小伙伴們可以參考一下2016-08-08

