React?Redux管理庫(kù)示例詳解
前言:
什么是redux?redux和vuex一樣,都被統(tǒng)稱(chēng)為狀態(tài)管理庫(kù),是核心數(shù)據(jù)存貯與分發(fā)、監(jiān)聽(tīng)數(shù)據(jù)改變的核心所在。
可以簡(jiǎn)單說(shuō)下redux和vuex的區(qū)別:
相同點(diǎn)
- state 共享數(shù)據(jù)
- 流程一致:定義全局state,觸發(fā),修改state
- 原理相似,通過(guò)全局注入store。
不同點(diǎn)
- vuex定義了state、getter、mutation、action四個(gè)對(duì)象;redux定義了state、reducer、action。
- vuex觸發(fā)方式有兩種commit同步和dispatch異步;redux同步和異步都使用dispatch
- vuex中state統(tǒng)一存放,方便理解;reduxstate依賴(lài)所有reducer的初始值
- vuex有g(shù)etter,目的是快捷得到state;redux沒(méi)有這層,react-redux mapStateToProps參數(shù)做了這個(gè)工作。
- vuex中mutation只是單純賦值(很淺的一層);redux中reducer只是單純?cè)O(shè)置新state(很淺的一層)。他倆作用類(lèi)似,但書(shū)寫(xiě)方式不同
- vuex中action有較為復(fù)雜的異步ajax請(qǐng)求;redux中action中可簡(jiǎn)單可復(fù)雜,簡(jiǎn)單就直接發(fā)送數(shù)據(jù)對(duì)象({type:xxx, your-data}),復(fù)雜需要調(diào)用異步ajax(依賴(lài)redux-thunk插件)。
- Redux 使用的是不可變數(shù)據(jù),而Vuex的數(shù)據(jù)是可變的。Redux每次都是用新的state替換舊的state,而Vuex是直接修改
- Redux 在檢測(cè)數(shù)據(jù)變化的時(shí)候,是通過(guò) diff 的方式比較差異的,而Vuex其實(shí)和Vue的原理一樣,是通過(guò) getter/setter來(lái)比較的
vuex 數(shù)據(jù)交互 思維圖:

redux數(shù)據(jù)交互思維圖:

接下來(lái)詳細(xì)說(shuō)說(shuō)redux:
配置總共分為三部分
一.actions:負(fù)責(zé)收集并向reduces提交state的變化,自身可分為兩部分actions類(lèi)型和actions函數(shù)創(chuàng)建
(1)actions —type 常量類(lèi)型,主負(fù)責(zé)向reduces
(2)actions —fn 函數(shù)創(chuàng)建 組件中觸發(fā)提交函數(shù)
二.reducers 更新state狀態(tài),可根據(jù)state數(shù)據(jù)類(lèi)型拆分成單個(gè)reducer,把reducers細(xì)化,后面通過(guò)集合構(gòu)建出最終的大state
三.全局只需要有一個(gè)store,不需要像網(wǎng)站中資料介紹的在每一個(gè)組件一樣去初始化一個(gè)store,一個(gè)項(xiàng)目集合在這初始化一次就可以;
store.dispatch() // 提交
store.sbuscribe() // 組件中監(jiān)聽(tīng)reducer的變化,即state的變化回調(diào)
store.getState() // 獲取state的值,通常和store.sbuscribe() 結(jié)合使用
源碼部分:
目錄配置

actions:
index.js
/* actions 類(lèi)型
* TYPE_GET_LIST 這是一個(gè)關(guān)于點(diǎn)擊類(lèi)型獲取列表的定義
*/
import {TYPE_GET_LIST,IS_LOGIN} from "./type"
/* actions 創(chuàng)建函數(shù)
*actions 創(chuàng)建函數(shù)和actions是兩個(gè)概念
*/
export function getType(opt){
return {type: TYPE_GET_LIST, opt}
}
export function isLogin(flag){
return {type: IS_LOGIN, flag}
}
type.js
/* actions 類(lèi)型type */
export const TYPE_GET_LIST = "TYPE_GET_LIST";
export const IS_LOGIN = "IS_LOGIN";
/* 其他常量 */
export const otherType = {
TO_DO: "TO_DO"
}
reducers
index.js
/**
* redux 管理入口
*/
import {combineReducers} from "redux"
import userBasketReducer from './userReducer';
import {TYPE_GET_LIST, IS_LOGIN} from "../actions/type"
/* 不同數(shù)據(jù)結(jié)構(gòu)的單個(gè)state */
function typeInfo(state={}, action) {
console.log(state, action, "這個(gè)是tyInfo的信息");
switch (action.type) {
case TYPE_GET_LIST: return Object.assign({}, state, {typeInfo: action.opt});
default: return state;
}
};
function isLogin(state=false, action) {
console.log(state, action);
switch (action.type) {
case IS_LOGIN: return Object.assign({}, state, {isLogin: action.flag});
case ....; //
default: return state;
}
};
// 匯總成一個(gè)大的state,供全局使用
const reducers = combineReducers({
userBasket: userBasketReducer,
typeInfo,
isLogin
});
export default reducers;store
import { createStore } from 'redux'
import reducers from '../reducers'
const store = createStore(reducers)
export default store;
至此,一個(gè)完整的redux搭建成功,需要拓展什么樣的業(yè)務(wù)只需要根據(jù)自己的業(yè)務(wù)定義常量函數(shù)名和創(chuàng)建函數(shù)就可以了,然后通過(guò)在組件中dispatch分發(fā)的方式提交,就能直接掛載到state對(duì)象上供組件間相互使用。
接下來(lái)看看如何在組件中使用:
如何提交:
在組件中引入store庫(kù),和函數(shù)創(chuàng)建的方法
import {isLogin} from "../../redux/actions"
import store from "../../redux/store";
// 提交
store.dispatch(isLogin({flag: true})) // 登錄成功賦值更新已登錄邏輯如何動(dòng)態(tài)獲取監(jiān)聽(tīng)改變的值監(jiān)聽(tīng),全局監(jiān)聽(tīng)state的值
import store from "../../redux/store";
store.subscribe(() => {
const { selectedFolderId } = store.getState().selectedFolderId;
this.setState({
checkFolderId: selectedFolderId
});
});
Redux 將組件區(qū)分為 容器組件 和 UI 組件
- 前者會(huì)處理邏輯
- 后者只負(fù)責(zé)顯示和交互,內(nèi)部不處理邏輯,狀態(tài)完全由外部掌控
Provider
看我上邊那個(gè)代碼的頂層組件4個(gè)字。對(duì),你沒(méi)有猜錯(cuò)。這個(gè)頂級(jí)組件就是Provider,一般我們都將頂層組件包裹在Provider組件之中,這樣的話(huà),所有組件就都可以在react-redux的控制之下了,但是store必須作為參數(shù)放到Provider組件中去
<Provider store = {store}>
<App />
<Provider>
這個(gè)組件的目的是讓所有組件都能夠訪問(wèn)到Redux中的數(shù)據(jù)。
connect 的使用:
connect(mapStateToProps, mapDispatchToProps)(MyComponent)
mapStateToProps 把Redux中的數(shù)據(jù)映射到React中的props中去。
如:
const mapStateToProps = (state) => {
return {
// prop : state.xxx | 意思是將state中的某個(gè)數(shù)據(jù)映射到props中
foo: state.bar
}
}
組件中:
class Foo extends Component {
constructor(props){
super(props);
}
render(){
return(
// 這樣子渲染的其實(shí)就是state.bar的數(shù)據(jù)了
<div>this.props.foo</div>
)
}
}
Foo = connect()(Foo);
export default Foo;
mapDispatchToProps 把各種dispatch也變成了props讓你可以直接使用
const mapDispatchToProps = (dispatch) => { // 默認(rèn)傳遞參數(shù)就是dispatch
return {
onClick: () => {
dispatch({
type: 'increatment'
});
}
};
}
class Foo extends Component {
constructor(props){
super(props);
}
render(){
return(
<button onClick = {this.props.onClick}>點(diǎn)擊increase</button>
)
}
}
Foo = connect()(Foo);
export default Foo;
可以直接通過(guò)this.props.onClick,來(lái)調(diào)用dispatch,這樣子就不需要在代碼中來(lái)進(jìn)行store.dispatch了
如果哪兒不懂可以留言我會(huì)快速回復(fù),拆分的比較細(xì),有些地方可能沒(méi)必要拆分,完全是為了自己練習(xí)和做個(gè)筆記,也方便大家閱讀
到此這篇關(guān)于React Redux管理庫(kù)示例詳解的文章就介紹到這了,更多相關(guān)React Redux內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
next-redux-wrapper使用細(xì)節(jié)及源碼分析
這篇文章主要為大家介紹了next-redux-wrapper使用細(xì)節(jié)及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
create-react-app使用antd按需加載的樣式無(wú)效問(wèn)題的解決
這篇文章主要介紹了create-react-app使用antd按需加載的樣式無(wú)效問(wèn)題的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
react如何使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容
本文介紹了如何模仿抖音發(fā)布頁(yè)面,使用div元素作為輸入框,并利用CSS樣式和JavaScript動(dòng)態(tài)操作DOM,實(shí)現(xiàn)類(lèi)似于input輸入框的功能,感興趣的朋友跟隨小編一起看看吧2024-10-10
詳解React中父子組件數(shù)據(jù)傳遞和修改的方式及原理
這篇文章主要為大家詳細(xì)介紹了React中父子組件數(shù)據(jù)傳遞和修改的方式及原理,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
React jsx轉(zhuǎn)換與createElement使用超詳細(xì)講解
這篇文章主要介紹了React jsx轉(zhuǎn)換與createElement使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-11-11

