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

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

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

react中的redux

作者:qq_45689385 更新時間: 2022-07-21 編程語言

一、redux簡介

? ? ? ? ? ? ?官網(wǎng)稱之為 JS 應(yīng)用的狀態(tài)容器,提供可預(yù)測的狀態(tài)管理,并且可以與前端三大框架搭配,但是vue中有自己團(tuán)隊的vuex,一般與react配合使用,在我個人理解為,這可以提高數(shù)據(jù)可用性,當(dāng)同一條數(shù)據(jù)在多個組件中都要調(diào)用時,這個時候就可以用狀態(tài)容器進(jìn)行存儲調(diào)用或者對改狀態(tài)進(jìn)行操作

二、根據(jù)原理圖進(jìn)行解析

ReactComponents:當(dāng)前需要使用狀態(tài)管理的組件,在組件中需要引入store,通store.getState()獲取state值,通過ActionCreators進(jìn)行像store發(fā)送改變狀態(tài)的內(nèi)容

ActionCreators:用dispatch通知store要改變,action兩個值:type(類型,根據(jù)type來判斷如何加工數(shù)據(jù)),data(需要處理的值)

Store:存放處理好的數(shù)據(jù)。可以通過接收到新的dispatch像reducers派發(fā)更新任務(wù)

Reducers:根據(jù)接收到的任務(wù),進(jìn)行對state的改變,接收兩個參數(shù):previousState(前一個值),action就是dispatch中的那個參數(shù),再根據(jù)type類型判斷如何操作,最后把新的狀態(tài)返回到store

如圖

示例

下載npm install redux 在redux文件夾下

?創(chuàng)建store.js

/* 
	該文件專門用于暴露一個store對象,整個應(yīng)用只有一個store對象
*/

//引入createStore,專門用于創(chuàng)建redux中最為核心的store對象
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

/* 
	該文件專門為Count組件生成action對象
*/

//同步action,就是指action的值為Object類型的一般對象
export const increment = data => ({type:'increment',data})
export const decrement = data => ({type:'decrement',data})

?創(chuàng)建reducer文件夾,在該文件夾下創(chuàng)建count.js

/* 
	1.該文件是用于創(chuàng)建一個為Count組件服務(wù)的reducer,reducer的本質(zhì)就是一個函數(shù)
	2.reducer函數(shù)會接到兩個參數(shù),分別為:之前的狀態(tài)(preState),動作對象(action)
*/

const initState = 0 //初始化狀態(tài)
export default function countReducer(preState=initState,action){
	// console.log(preState);
	//從action對象中獲取: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,專門用于創(chuàng)建action對象
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>
		)
	}
}

注意,此時狀態(tài)是改變了,但是頁面沒有跟新

可以 通過subscribe訂閱監(jiān)聽store中值的改變,在利用react中的setState特性驅(qū)動頁面更新,如下

componentDidMount(){
	//檢測redux中狀態(tài)的變化,只要變化,就調(diào)用render
	 store.subscribe(()=>{
	  this.setState({})
	})
} 

如果是異步加載,需要下載redux-thunk依賴

?首先在store中引入,在createStore第二個參數(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中使用與同步的一樣,只不過多了一個時間參數(shù)

//異步action,就是指action的值為函數(shù),異步action中一般都會調(diào)用同步action
export const createIncrementAsyncAction = (data,time) => {
	return (dispatch)=>{
		setTimeout(()=>{
			dispatch(createIncrementAction(data))
		},time)
	}
}

注意:reducer中的函數(shù)都是純函數(shù),不能直接更改傳入的值然后返回,這樣頁面不會跟新,需要用一個新的參數(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: //若是添加一個人
			//preState.unshift(data) //此處不可以這樣寫,這樣會導(dǎo)致preState被改寫了,personReducer就不是純函數(shù)了。
			return [data,...preState]
		default:
			return preState
	}
}

這就是一個簡單完整的demo?

三、?react-redux

? ? ? ? ? ? ? ?顧名思義,基于react封裝的,主體操作模型如下

? ? ? ? ? ? ? 1、所有的ui組件都是包裹在一個容器組件,他們是父子關(guān)系

? ? ? ? ? ? ? 2、容器組件可以正常使用redux的api,而ui組件不能直接使用,容器組件會用porps的方式把redux中所保存的狀態(tài)和用于操作的方法傳給ui組件

? ? ? ? ? ? ? ?如下圖

對了,react-redix是不需要subscribe來監(jiān)聽state的變化,能自動響應(yīng)state的變化,然后重新渲染render?

基礎(chǔ)用法如下(本用法是基于上一個redux之上的)

首先在父組件中引入store傳入父組件, 為方便組件后代都能接收到store,省的在每個父組件中引入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')
)

然后編寫 容器組件 和 ui組件 可以把容器組件 和 ui組件 集成在一個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)建并暴露一個Count的容器組件
    2.connect 兩個參 mapStateToProps 和 mapDispatchToProps
      mapStateToProps:
       	1.mapStateToProps函數(shù)返回的是一個對象;
	    2.返回的對象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value
	    3.mapStateToProps用于傳遞狀態(tài)
      mapDispatchToProps:
	   1.mapDispatchToProps函數(shù)返回的是一個對象;
	   2.返回的對象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value
	   3.mapDispatchToProps用于傳遞操作狀態(tài)的方法
*/
export default connect(
	state => ({
		count:state
	}),
	{increment,decrement} //傳入action
)(Count)

最后

可以把所有的reduce匯眾到一個文件,然后傳入combineReducers函數(shù),在引入store中,這樣就可以用state.count 或某一個值得到不同的數(shù)據(jù),替代原先的countReducer

在reducer文件夾下新建 index.js文件

/* 
	該文件用于匯總所有的reducer為一個總的reducer
*/
//引入combineReducers,用于匯總多個reducer
import {combineReducers} from 'redux'
//引入為Count組件服務(wù)的reducer
import count from './count'
//引入為Person組件服務(wù)的reducer
import persons from './person'

//匯總所有的reducer變?yōu)橐粋€總的reducer
export default  combineReducers({
	count,
	persons
})

原文鏈接:https://blog.csdn.net/qq_45689385/article/details/124390603

欄目分類
最近更新