手把手教會(huì)你使用redux的入門教程
Redux詳解
Redux介紹
Redux 是 JavaScript 應(yīng)用的狀態(tài)容器,提供可預(yù)測(cè)的狀態(tài)管理。
在Redux中有3個(gè)原則
單一數(shù)據(jù)源
整個(gè)應(yīng)用的
State被儲(chǔ)存在一棵 object tree 中,并且這個(gè) object tree 只存在于唯一一個(gè)Stroe中。State 是只讀的
唯一改變
State的方法就是觸發(fā)Actions,Actions是一個(gè)用于描述已發(fā)生事件的普通對(duì)象。使用純函數(shù)來執(zhí)行修改
為了描述
Actions如何改變 State tree ,你需要編寫Reducers。
如下圖所示,在Redux中,有一個(gè)全局狀態(tài)存儲(chǔ)器Store,只有Actions才能去進(jìn)行修改Store中的數(shù)據(jù),其更改數(shù)據(jù)這一過程,即store.dispatch(action)就是為Reducers。當(dāng)Actions修改完Store中的數(shù)據(jù)后,Store會(huì)通知對(duì)應(yīng)頁(yè)面其數(shù)據(jù)發(fā)送改變。

Redux有什么作用
得益于react是單項(xiàng)數(shù)據(jù)流的關(guān)系,在react框架中要統(tǒng)籌全局?jǐn)?shù)據(jù)就顯得較為繁瑣,需要通過父子間的組件傳遞/或者是Context才能進(jìn)行跨組件交流,但在react里,context是個(gè)反模式的東西,不同于redux等的細(xì)粒度響應(yīng)式更新,context的值一旦變化,所有依賴該context的組件全部都會(huì)force update,因?yàn)閏ontext API并不能細(xì)粒度地分析某個(gè)組件依賴了context里的哪個(gè)屬性,并且它可以穿透React.memo和shouldComponentUpdate的對(duì)比,把所有涉事組件強(qiáng)制刷新。
Context 設(shè)計(jì)目的是為了共享那些對(duì)于一個(gè)組件樹而言是“全局”的數(shù)據(jù),例如當(dāng)前認(rèn)證的用戶、主題或首選語(yǔ)言。
如何在React中使用Redux
React中使用的是react-redux這個(gè)三方包
這里借用下大佬圓兒圈圈繪制的流程圖,大致流程如下

react-redux中的connect方法將store上的getState 和 dispatch 包裝成組件的props。
如何使用React-redux
舉個(gè)todoList的栗子
在需要共享數(shù)據(jù)的主入口,先引入redux和react-redux,再引入 createStore 來創(chuàng)建組件共享的數(shù)據(jù),這個(gè)是 redux 中提供的一個(gè)方法,我們直接引入,并將主入口文件用Provider包裹一下。
import React, { Component } from 'react';
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from './redux/reducer/index'
import AddItemPage from './components/index'
const store = createStore(reducer) //使用createStore創(chuàng)建個(gè)store
export default class App extends Component {
render() {
return (<Provider store={store}> //todoList共享store
<AddItemPage/> //todoList頁(yè)面
</Provider>)
}
}然后去定義action和reducer的初始狀態(tài),因?yàn)樵趓educer中已經(jīng)設(shè)置了state的初始值為[],故不作定義state
reducer的
import { combineReducers } from 'redux'
?
const addItem = (state = [], action) => {
switch (action.type) {
case 'ADD_ITEM':
return [
...state,
{
id: action.id,
text: action.text,
isDelete: false
}
]
case 'DELETE_ITEM':
let newState = [...state]
console.log(newState)
action.id.map(item=>{
newState.splice(item.id,1)
})
return newState
default:
return state
}
}
export default combineReducers({
addItem
})action
let nextItemId = 0
export const addTodo = text => ({
type: 'ADD_ITEM',
id: nextItemId++,
text
})
?
export const deleteItem = id => ({
type: 'DELETE_ITEM',
id
})然后再模塊中將定義的action以及reducer返回的state鏈接到模塊中
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { addTodo,deleteItem } from '../redux/action'
import ItemList from './itemList'
?
class AddItem extends Component {
render() {
const { addItem,doAdd,doDelete } = this.props
return <>
<div>
<form onSubmit={e => {
e.preventDefault()
if (!this.input.value.trim()) {
return
}
doAdd(this.input.value)
// this.props.dispatch(addTodo(this.input.value))
this.input.value = ''
}}>
<input ref={node => this.input = node} />
<button type="submit">
添加
</button>
<button type="button" onClick={(e)=>{
let arr = []
const checkbox = document.getElementsByName('itemId').forEach(item=> {
if(item.checked) arr.push(item.value)
})
doDelete(arr)
// this.props.dispatch(deleteItem(arr))
}}>
刪除
</button>
</form>
</div>
<ItemList addItem={addItem}/>
</>
}
}
const mapStateToProps = state => {return ({...state})}
const mapDispatchToProps = dispatch => ({
doAdd:(value)=>dispatch(addTodo(value)),
doDelete:(arr)=>dispatch(deleteItem(arr))
})
?
export default connect(
mapStateToProps,
mapDispatchToProps
)(AddItem)import React, { Component } from 'react';
class itemList extends Component {
render() {
return <>
{
this.props.addItem.map(item=>{
return <div key={item.id} {...item}>
<input type='checkbox' name='itemId' value={item?.id}/>
<li
style={{
textDecoration: item?.completed ? 'line-through' : 'none'
}}
>
{item?.text}
</li>
</div>
})
}
</>;
}
}
?
export default itemList即可,
可以看到輸入123,點(diǎn)擊添加的時(shí)候觸發(fā)了ADD_ITEM的操作

點(diǎn)擊刪除的時(shí)候觸發(fā)了DELETE_ITEM操作

到此這篇關(guān)于手把手教會(huì)你使用redux的入門教程的文章就介紹到這了,更多相關(guān)redux入門內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序連接MySQL數(shù)據(jù)庫(kù)的全過程
微信小程序是不能直接連接數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)操作的,這是出于安全的考慮,下面這篇文章主要給大家介紹了關(guān)于微信小程序連接MySQL數(shù)據(jù)庫(kù)的全過程,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01
UniApp?WebView頁(yè)面中的請(qǐng)求跨域問題解決
在使用UniApp開發(fā)中,通過WebView組件加載本地網(wǎng)頁(yè)時(shí),往往會(huì)遇到跨域問題,下面這篇文章主要介紹了UniApp?WebView頁(yè)面中的請(qǐng)求跨域問題解決的相關(guān)資料,需要的朋友可以參考下2024-10-10
javascript取消文本選定的實(shí)現(xiàn)代碼
最近在做拖動(dòng)布局. 發(fā)現(xiàn)有文本選定的時(shí)候, 進(jìn)行拖動(dòng)很不好看.2010-11-11
基于JavaScript實(shí)現(xiàn)前端數(shù)據(jù)多條件篩選功能
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)前端數(shù)據(jù)多條件篩選功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
js獲取所有checkbox的值的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)硪黄猨s獲取所有checkbox值的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05
JavaScript知識(shí)點(diǎn)總結(jié)(五)之Javascript中兩個(gè)等于號(hào)(==)和三個(gè)等于號(hào)(===)的區(qū)別
這篇文章主要介紹了JavaScript知識(shí)點(diǎn)總結(jié)(五)之Javascript中兩個(gè)等于號(hào)(==)和三個(gè)等于號(hào)(===)的區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-05-05
javascript實(shí)現(xiàn)動(dòng)態(tài)改變層大小的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)動(dòng)態(tài)改變層大小的方法,涉及javascript操作頁(yè)面屬性的相關(guān)技巧,需要的朋友可以參考下2015-05-05

