日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

react中的redux

作者:qq_45689385 更新時(shí)間: 2022-07-21 編程語(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>&nbsp;
				<button onClick={this.increment}>+</button>&nbsp;
				<button onClick={this.decrement}>-</button>&nbsp;
			</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>&nbsp;
				<button onClick={this.increment}>+</button>&nbsp;
				<button onClick={this.decrement}>-</button>&nbsp;
			</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

欄目分類(lèi)
最近更新