網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、redux簡(jiǎn)介
? ? ? ? ? ? ?官網(wǎng)稱(chēng)之為 JS 應(yīng)用的狀態(tài)容器,提供可預(yù)測(cè)的狀態(tài)管理,并且可以與前端三大框架搭配,但是vue中有自己團(tuán)隊(duì)的vuex,一般與react配合使用,在我個(gè)人理解為,這可以提高數(shù)據(jù)可用性,當(dāng)同一條數(shù)據(jù)在多個(gè)組件中都要調(diào)用時(shí),這個(gè)時(shí)候就可以用狀態(tài)容器進(jìn)行存儲(chǔ)調(diào)用或者對(duì)改狀態(tài)進(jìn)行操作
二、根據(jù)原理圖進(jìn)行解析
ReactComponents:當(dāng)前需要使用狀態(tài)管理的組件,在組件中需要引入store,通store.getState()獲取state值,通過(guò)ActionCreators進(jìn)行像store發(fā)送改變狀態(tài)的內(nèi)容
ActionCreators:用dispatch通知store要改變,action兩個(gè)值:type(類(lèi)型,根據(jù)type來(lái)判斷如何加工數(shù)據(jù)),data(需要處理的值)
Store:存放處理好的數(shù)據(jù)。可以通過(guò)接收到新的dispatch像reducers派發(fā)更新任務(wù)
Reducers:根據(jù)接收到的任務(wù),進(jìn)行對(duì)state的改變,接收兩個(gè)參數(shù):previousState(前一個(gè)值),action就是dispatch中的那個(gè)參數(shù),再根據(jù)type類(lèi)型判斷如何操作,最后把新的狀態(tài)返回到store
如圖
示例
下載npm install redux 在redux文件夾下
?創(chuàng)建store.js
/*
該文件專(zhuān)門(mén)用于暴露一個(gè)store對(duì)象,整個(gè)應(yīng)用只有一個(gè)store對(duì)象
*/
//引入createStore,專(zhuān)門(mén)用于創(chuàng)建redux中最為核心的store對(duì)象
import {createStore} from 'redux'
//引入為Count組件服務(wù)的reducer
import countReducer from './reducers/count.js'
//暴露store
export default createStore(countReducer)
?創(chuàng)建action文件夾,在該文件夾下創(chuàng)建count.js
/*
該文件專(zhuān)門(mén)為Count組件生成action對(duì)象
*/
//同步action,就是指action的值為Object類(lèi)型的一般對(duì)象
export const increment = data => ({type:'increment',data})
export const decrement = data => ({type:'decrement',data})
?創(chuàng)建reducer文件夾,在該文件夾下創(chuàng)建count.js
/*
1.該文件是用于創(chuàng)建一個(gè)為Count組件服務(wù)的reducer,reducer的本質(zhì)就是一個(gè)函數(shù)
2.reducer函數(shù)會(huì)接到兩個(gè)參數(shù),分別為:之前的狀態(tài)(preState),動(dòng)作對(duì)象(action)
*/
const initState = 0 //初始化狀態(tài)
export default function countReducer(preState=initState,action){
// console.log(preState);
//從action對(duì)象中獲取:type、data
const {type,data} = action
//根據(jù)type決定如何加工數(shù)據(jù)
switch (type) {
case 'increment': //如果是加
return preState + data
case 'decrement': //若果是減
return preState - data
default:
return preState
}
}
最后就是在component組件中調(diào)用
import React, { Component } from 'react'
//引入store,用于獲取redux中保存狀態(tài)
import store from '../../redux/store'
//引入actionCreator,專(zhuān)門(mén)用于創(chuàng)建action對(duì)象
import {
createIncrementAction,
createDecrementAction
} from '../../redux/actions/count'
export default class Count extends Component {
state = {carName:'奔馳c63'}
//加法
increment = ()=>{
const {value} = this.selectNumber
store.dispatch(createIncrementAction(value*1))
}
//減法
decrement = ()=>{
const {value} = this.selectNumber
store.dispatch(createDecrementAction(value*1))
}
render() {
return (
<div>
<h1>當(dāng)前求和為:{store.getState()}</h1>
<select ref={c => this.selectNumber = c}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}
注意,此時(shí)狀態(tài)是改變了,但是頁(yè)面沒(méi)有跟新
可以 通過(guò)subscribe訂閱監(jiān)聽(tīng)store中值的改變,在利用react中的setState特性驅(qū)動(dòng)頁(yè)面更新,如下
componentDidMount(){
//檢測(cè)redux中狀態(tài)的變化,只要變化,就調(diào)用render
store.subscribe(()=>{
this.setState({})
})
}
如果是異步加載,需要下載redux-thunk依賴(lài)
?首先在store中引入,在createStore第二個(gè)參數(shù)中添加 applyMiddleware(thunk)
import {createStore,applyMiddleware} from 'redux'
import countReducer from './reducers/count.js'
//引入redux-thunk,用于支持異步action
import thunk from 'redux-thunk'
//暴露store
export default createStore(countReducer,applyMiddleware(thunk))
在action文件下的count.js中添加,在component中使用與同步的一樣,只不過(guò)多了一個(gè)時(shí)間參數(shù)
//異步action,就是指action的值為函數(shù),異步action中一般都會(huì)調(diào)用同步action
export const createIncrementAsyncAction = (data,time) => {
return (dispatch)=>{
setTimeout(()=>{
dispatch(createIncrementAction(data))
},time)
}
}
注意:reducer中的函數(shù)都是純函數(shù),不能直接更改傳入的值然后返回,這樣頁(yè)面不會(huì)跟新,需要用一個(gè)新的參數(shù)接收返回,然后返回,案例如下
import {ADD_PERSON} from '../constant'
//初始化人的列表
const initState = [{id:'001',name:'tom',age:18}]
export default function personReducer(preState=initState,action){
// console.log('personReducer@#@#@#');
const {type,data} = action
switch (type) {
case ADD_PERSON: //若是添加一個(gè)人
//preState.unshift(data) //此處不可以這樣寫(xiě),這樣會(huì)導(dǎo)致preState被改寫(xiě)了,personReducer就不是純函數(shù)了。
return [data,...preState]
default:
return preState
}
}
這就是一個(gè)簡(jiǎn)單完整的demo?
三、?react-redux
? ? ? ? ? ? ? ?顧名思義,基于react封裝的,主體操作模型如下
? ? ? ? ? ? ? 1、所有的ui組件都是包裹在一個(gè)容器組件,他們是父子關(guān)系
? ? ? ? ? ? ? 2、容器組件可以正常使用redux的api,而ui組件不能直接使用,容器組件會(huì)用porps的方式把redux中所保存的狀態(tài)和用于操作的方法傳給ui組件
? ? ? ? ? ? ? ?如下圖
對(duì)了,react-redix是不需要subscribe來(lái)監(jiān)聽(tīng)state的變化,能自動(dòng)響應(yīng)state的變化,然后重新渲染render?
基礎(chǔ)用法如下(本用法是基于上一個(gè)redux之上的)
首先在父組件中引入store傳入父組件, 為方便組件后代都能接收到store,省的在每個(gè)父組件中引入store,我就直接在最外面的最外面的index.js中用Provider處理了
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './redux/store'
import {Provider} from 'react-redux'
ReactDOM.render(
/* 此處需要用Provider包裹App,目的是讓App所有的后代容器組件都能接收到store */
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)
然后編寫(xiě) 容器組件 和 ui組件 可以把容器組件 和 ui組件 集成在一個(gè)jsx文件中
import React, { Component } from 'react'
//引入action
import {
increment,
decrement
} from '../../redux/actions/count'
//引入connect用于連接UI組件與redux
import {connect} from 'react-redux'
//定義UI組件
class Count extends Component {
//加法
increment = ()=>{
const {value} = this.selectNumber
this.props.increment(value*1)
}
//減法
decrement = ()=>{
const {value} = this.selectNumber
this.props.decrement(value*1)
}
render() {
//console.log('UI組件接收到的props是',this.props);
return (
<div>
<h4>當(dāng)前求和為:{this.props.count}</h4>
<select ref={c => this.selectNumber = c}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}
/*
1.使用connect()()創(chuàng)建并暴露一個(gè)Count的容器組件
2.connect 兩個(gè)參 mapStateToProps 和 mapDispatchToProps
mapStateToProps:
1.mapStateToProps函數(shù)返回的是一個(gè)對(duì)象;
2.返回的對(duì)象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value
3.mapStateToProps用于傳遞狀態(tài)
mapDispatchToProps:
1.mapDispatchToProps函數(shù)返回的是一個(gè)對(duì)象;
2.返回的對(duì)象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value
3.mapDispatchToProps用于傳遞操作狀態(tài)的方法
*/
export default connect(
state => ({
count:state
}),
{increment,decrement} //傳入action
)(Count)
最后
可以把所有的reduce匯眾到一個(gè)文件,然后傳入combineReducers函數(shù),在引入store中,這樣就可以用state.count 或某一個(gè)值得到不同的數(shù)據(jù),替代原先的countReducer
在reducer文件夾下新建 index.js文件
/*
該文件用于匯總所有的reducer為一個(gè)總的reducer
*/
//引入combineReducers,用于匯總多個(gè)reducer
import {combineReducers} from 'redux'
//引入為Count組件服務(wù)的reducer
import count from './count'
//引入為Person組件服務(wù)的reducer
import persons from './person'
//匯總所有的reducer變?yōu)橐粋€(gè)總的reducer
export default combineReducers({
count,
persons
})
原文鏈接:https://blog.csdn.net/qq_45689385/article/details/124390603
相關(guān)推薦
- 2024-03-07 SpringIoC-基于XML配置方式組件管理
- 2022-08-03 python數(shù)據(jù)類(lèi)型可變與不可變深入分析_python
- 2022-07-27 Go?error的使用方式詳解_Golang
- 2022-03-30 Android?RecyclerView曝光采集的實(shí)現(xiàn)方法_Android
- 2022-12-05 一文教你如何優(yōu)雅處理Golang中的異常_Golang
- 2023-10-09 所有的引用類(lèi)型都有自由可拓展性怎么理解
- 2022-10-25 golang值接收者和指針接收者的區(qū)別介紹_Golang
- 2022-08-28 Go通道channel通過(guò)通信共享內(nèi)存_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支