網站首頁 編程語言 正文
1、react-redux
react-redux把組件分為兩類,一類叫做UI組件,一類叫做容器組件;
UI組件的外側都要包裹一個容器組件。
注意??:本文使用的示例為之前的文章中的示例。在之前的文章中已經做過了介紹,在本文就不再闡述。
建議閱讀順序是:
【redux工作流程】
【redux異步action】
??再到本文
2、連接容器組件與UI組件
UI組件存放在components文件夾中,我們可以在src目錄下新建文件夾containers,專門用于存放容器組件
例如:Count組件的容器組件:/src/containers/Count/index.jsx
/*
該組件是Count組件這個UI組件的容器組件
*/
// 引入Count組件的UI組件
import CountUI from '../../components/Count'
// 引入connect用于連接UI組件與容器組件
import { connect } from 'react-redux'
//創建并暴露一個Count的容器組件,connect()()的含義是:調用connect()這個函數返回的函數
export default connect()(CountUI)
代碼解釋:
引入CountUI,為Count組件的UI組件,從原理圖中來看,該組件是Count容器組件的子組件。
引入connect函數,用于連接UI組件與容器組件;
我們從原理圖中可以看出,redux要想工作,必須要連接UI組件與容器組件,還必須連接容器組件與store。
那么我們在容器組件中,使用connect()()的方法連接了UI組件
【connect()()的含義:調用connect()這個函數的返回值,返回值本身是一個函數,也就是調用返回的函數】
現在還需要讓容器組件與store建立起連接;
怎么讓容器組件與store建立起連接呢?
我們之前在App組件中一直都是渲染Count的UI組件的,但是我們現在引入了Count的容器組件(為Count的UI組件的父組件),那么我們可以直接在App組件中直接渲染Count組件的容器組件:
// App.jsx
import React, { Component } from 'react'
import Count from './containers/Count'
import store from './redux/store'
export default class App extends Component {
render() {
return (
<div>
{/* 給容器組件傳遞store */}
<Count store={store} />
</div>
)
}
}
重點??在于,
在渲染Count組件的容器組件時,通過組件的props屬性,將store傳入Count組件的容器組件,從而實現容器組件與store建立起連接。
3、react-redux基本使用
現在我們已經把UI組件與容器組件建立起連接了,并且將容器組件與store也建立起連接了,那么我們接下來一起來探索react-redux是怎么工作,如何使用的呢?
從流程圖可以看出,我們需要向UI組件傳遞state(狀態)和dispatch(操作狀態的方法)。
但是我們在UI組件的父組件,也就是Count的容器組件中,并沒有以組件標簽()的形式去渲染子組件
而是通過react-redux提供的connect方法將父子組件建立起的聯系,我們就需要通過connect方法傳遞props。
我們之前知道,我們在調用connect方法返回的函數時需要傳遞UI組件作為參數,以將容器組件與UI組件連接起來,也就是
connect()(CountUI)
而傳遞props時,我們需要在調用connect方法時直接傳入兩個參數(也就是connect的第一個括號內的參數),并且這兩個參數都是函數形式的參數。具體看代碼吧~
connect(mapStateToProps, mapDispatchToProps)(CountUI)
說明:第一個函數參數mapStateToProps作用是將存放在store中的狀態映射給UI組件的props;
第二個函數參數mapDispatchToProps作用是將操作數據的方法映射給UI組件的props;
其實也就對應圖中的
具體實現如下:
/*
該組件是Count組件這個UI組件的容器組件
*/
import CountUI from '../../components/Count'
import { connect } from 'react-redux'
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action_creator'
/*
1.mapStateToProps函數返回的是一個對象;
2.返回的對象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value
3.mapStateToProps用于傳遞狀態
*/
function mapStateToProps(state) {
return { count: state }
}
function mapDispatchToProps(dispatch) {
return {
jia: (data) => {
// 通知redux執行加法
dispatch(createIncrementAction(data))
},
jian: (data) => {
dispatch(createDecrementAction(data))
},
jiaAsync: (data, time) => {
dispatch(createIncrementAsyncAction(data, time))
}
}
}
//創建并暴露一個Count的容器組件,connect()()的含義是:調用connect()這個函數返回的函數
export default connect(mapStateToProps, mapDispatchToProps)(CountUI)
這樣一來,Count的UI組件就會接收到傳遞進來的props,我們可以通過props去渲染狀態和操作狀態:
/src/components/Count/index.jsx:
渲染狀態:
<h1>當前求和為:{this.props.count}</h1>
操作狀態:
// 加法
increment = () => {
const { value } = this.selectedNumber
this.props.jia(value * 1)
}
// 減法
decrement = () => {
const { value } = this.selectedNumber
this.props.jian(value * 1)
}
// 和為奇數時,加
incrementIfOdd = () => {
const { value } = this.selectedNumber
if (this.props.count % 2 !== 0) {
this.props.jia(value * 1)
}
}
// 異步加
incrementAsync = () => {
const { value } = this.selectedNumber
this.props.jiaAsync(value * 1, 500)
}
react-redux基本使用總結:
明確兩個概念:UI組件與容器組件
UI組件:不能使用任何redux的api,只負責頁面的呈現、交互等等;
容器組件:負責和redux通信,將結果交給UI組件
如何創建一個容器組件——靠react-redux 的 connect函數
connect(mapStateToProps, mapDispatchToProps)(CountUI)
mapStateToProps——映射狀態,返回值是一個對象;
mapDispatchToProps——映射操作狀態的方法,返回值是一個對象
備注:容器組件中的store是靠props傳入的,而不是在容器組件中直接引入。
優化1、簡寫mapState和mapDispatch兩個映射方法
原映射方法:
function mapStateToProps(state) {
return { count: state }
}
function mapDispatchToProps(dispatch) {
return {
jia: (data) => {
// 通知redux執行加法
dispatch(createIncrementAction(data))
},
jian: (data) => {
dispatch(createDecrementAction(data))
},
jiaAsync: (data, time) => {
dispatch(createIncrementAsyncAction(data, time))
}
}
}
簡寫成箭頭函數:
const mapStateToProps = state => ({ count: state })
const mapDispatchToProps = dispatch => (
{
jia: (data) => {
// 通知redux執行加法
dispatch(createIncrementAction(data))
},
jian: (data) => {
dispatch(createDecrementAction(data))
},
jiaAsync: (data, time) => {
dispatch(createIncrementAsyncAction(data, time))
}
}
)
當然,這只是在編碼的角度對函數進行簡化,我們還可以在API的角度,實現mapDispatch更為簡潔的寫法。
其實mapDispatchToProps還可以是一個對象,在一般寫法中,mapDispatchToProps是一個函數,但是可以簡寫成一個對象。
export default connect(
state => ({ count: state }),
// mapDispatchToProps的簡寫——是一個對象
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction
}
// mapDispatchToProps一般寫法——是一個函數
/* dispatch => (
{
jia: (data) => {
// 通知redux執行加法
dispatch(createIncrementAction(data))
},
jian: (data) => {
dispatch(createDecrementAction(data))
},
jiaAsync: (data, time) => {
dispatch(createIncrementAsyncAction(data, time))
}
}
) */
)(CountUI)
把mapDispatchToProps簡寫成一個對象的話,react-redux會自動分發,也就是底層自動調用dispatch方法,所以我們在書寫代碼時并不需要手動調用dispatch方法,在mapDispatchToProps簡寫成一個對象時可以省略dispatch,這就是屬于API層面的優化。
優化2、Provider組件的使用
在前面的連接容器組件和store的講解中,我們提出:要想連接容器組件和store,就需要在App.jsx中通過props將store傳入容器組件中。也就是這樣子的:
// App.jsx
import React, { Component } from 'react'
import Count from './containers/Count'
import store from './redux/store'
export default class App extends Component {
render() {
return (
<div>
{/* 給容器組件傳遞store */}
<Count store={store} />
</div>
)
}
}
現在我們基于react-redux,可以對App組件進行優化:
// App.jsx
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import Count from './containers/Count'
import store from './redux/store'
export default class App extends Component {
render() {
return (
<div>
{/* 給容器組件傳遞store */}
<Provider store={store}>
<Count />
</Provider>
</div>
)
}
}
這樣一來,哪怕我們需要連接多個容器組件到store,都只需要在渲染組件標簽的外圍包裹一個< Provider>標簽即可。
優化3、整合UI組件與容器組件
前面兩個優化,我們分別從代碼層面和API層面進行了優化。在這里,我們將在文件層面對UI組件和容器組件進行優化。
我們前面在逐步學習實踐react-redux時,將容器組件放在containers文件夾中。但是我們發現,如果需要使用redux的UI組件越來越多的話,需要的容器組件也越來越多,到最后可能項目中有20個組件需要使用redux中的狀態,那么我們真的就另外創建20個容器組件嗎?
Of course not ! Of course not! Ofcoursenot!
其實我們可以將UI組件與容器組件整合在同一個文件內!
/src/containers/Count/index.jsx:
import React, { Component } from 'react'
// 引入connect用于連接UI組件與容器組件
import { connect } from 'react-redux'
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action_creator'
// 定義UI組件Count
class Count extends Component {
// 加法
increment = () => {
const { value } = this.selectedNumber
this.props.jia(value * 1)
}
// 減法
decrement = () => {
const { value } = this.selectedNumber
this.props.jian(value * 1)
}
// 和為奇數時,加
incrementIfOdd = () => {
const { value } = this.selectedNumber
if (this.props.count % 2 !== 0) {
this.props.jia(value * 1)
}
}
// 異步加
incrementAsync = () => {
const { value } = this.selectedNumber
this.props.jiaAsync(value * 1, 500)
}
render() {
return (
<div>
<h1>當前求和為:{this.props.count}</h1>
<select ref={currentNode => { this.selectedNumber = currentNode }}>
<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>
<button onClick={this.incrementIfOdd}>和為奇數時,加</button>
<button onClick={this.incrementAsync}>異步加</button>
</div>
)
}
}
// 創建并暴露一個Count的容器組件,connect()()的含義是:調用connect()這個函數返回的函數
export default connect(
state => ({ count: state }),
// mapDispatchToProps的簡寫——是一個對象
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction
}
// mapDispatchToProps一般寫法——是一個函數
)(Count)
如此一來,我們就可以刪除/src/components/Count/index.jsx了~
優化總結
容器組件和UI組件整合為同一個文件
無需自己給容器組件傳遞store,給包裹一個標簽,在Provider內傳遞store即可;
使用了react-redux后也不用再自己監測redux中狀態的改變了,容器組件可以自動完成這個工作;
mapDispatchToProps也可以簡單的寫成一個對象;
一個組件要和redux“打交道”要經過哪幾步?
定義好UI組件——不暴露;引入connect生成一個容器組件,并暴露,寫法如下:
connect(
state => ({key:value}), //映射狀態
{key:xxxxAction} //映射操作狀態的方法
)(UI組件)
- 在UI組件中通過this.props讀取和操作狀態。
原文鏈接:https://blog.csdn.net/Svik_zy/article/details/125951641
相關推薦
- 2022-05-27 yolov5訓練時參數workers與batch-size的深入理解_python
- 2022-06-08 Api接口Sign簽名和驗簽
- 2022-10-27 教你使用Python?的?Template?類生成文件報告_python
- 2022-09-22 使用 sed 替換字符串中最后一次出現的字符
- 2023-04-29 React之關于Promise的用法_React
- 2022-07-08 C#中的圖像Image類與打印Printing類用法_C#教程
- 2022-05-27 C語言實現數獨小游戲_C 語言
- 2023-03-04 C++容器適配器的概念與示例_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支