亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Redux原理分析

cooxer / 2667人閱讀

摘要:原理分析是什么很多人認(rèn)為必須要結(jié)合使用,其實(shí)并不是的,是狀態(tài)容器,只要你的項(xiàng)目中使用到了狀態(tài),并且狀態(tài)十分復(fù)雜,那么你就可以使用管理你的項(xiàng)目狀態(tài),它可以使用在中,也可以使用中在中,當(dāng)然也適用其他的框架。

Redux原理分析

Redux是什么

很多人認(rèn)為redux必須要結(jié)合React使用,其實(shí)并不是的,Redux 是 JavaScript 狀態(tài)容器,只要你的項(xiàng)目中使用到了狀態(tài),并且狀態(tài)十分復(fù)雜,那么你就可以使用Redux管理你的項(xiàng)目狀態(tài),它可以使用在react中,也可以使用中在Vue中,當(dāng)然也適用其他的框架。
一.redux的工作原理

先上圖(圖片源于網(wǎng)絡(luò))

首先我們找到最上面的state

在react中state決定了視圖(ui),state的變化就會(huì)調(diào)用React的render()方法,從而改變視圖

用戶通過一些事件(如點(diǎn)擊按鈕,移動(dòng)鼠標(biāo))就會(huì)像reducer派發(fā)一個(gè)action

reducer接收到action后就會(huì)去更新state

store是包含了所有了state,可以把他看做所有狀態(tài)的集合

當(dāng)然,現(xiàn)在可能看不懂這在瞎說啥,但是等把這篇文章看完再來這個(gè)圖,和這段話,就會(huì)有恍然大明白的感覺

1.action

action本質(zhì)上就是一個(gè)對(duì)象,它一定有一個(gè)名為type的key 如{type: "add"},{type: "add"}就是一個(gè)action
但是我們只實(shí)際工作中并不是直接用action ,而是使用action創(chuàng)建函數(shù),(千萬(wàn)別弄混淆),
顧名思義action創(chuàng)建函數(shù)就是一個(gè)函數(shù),它的作用就是返回一個(gè)action,如:

function add() {
    return {type: "add"}
}
2.reducer

reducer其實(shí)就是一個(gè)函數(shù),它接收兩個(gè)參數(shù),第一個(gè)參數(shù)是需要管理的狀態(tài)state,第二個(gè)是action。reducer會(huì)根據(jù)傳入的action的type值對(duì)state進(jìn)行不同的操作,然后返回一個(gè)新的state,而不是在原有state的基礎(chǔ)上進(jìn)行修改,但是如果遇到了未知的(不匹配的)action,就會(huì)返回原有的state,不進(jìn)行任何改變。

function reducer(state = {money: 0}, action) {
    //返回一個(gè)新的state可以使用es6提供的Object.assign()方法,或擴(kuò)展運(yùn)算符(此方法需要babel-preset-state-3支持)
    switch (action.type) {
        case "+":
            return Object.assign({}, state, {money: state.money + 1});
        case "-":
            return {...state, ...{money: state.money - 1}};
        default:
            return state;
    }
}
3.store

你可以把store想成一個(gè)狀態(tài)樹,它包含了整個(gè)redeux應(yīng)用的所有狀態(tài)。
我們使用redux提供的createStore方法生成store

import {createStore} from "redux";
const store = createStore(reducer);

store提供了幾個(gè)方法供我們使用,下面是我們常用的3個(gè):

store.getState();//獲取整個(gè)狀態(tài)樹
store.dispatch();//改變狀態(tài),改變state的唯一方法
store.subscribe();//訂閱一個(gè)函數(shù),每當(dāng)state改變時(shí),都會(huì)去調(diào)用這個(gè)函數(shù)

接下來演示一個(gè)redux的完整應(yīng)用,并且說明這三個(gè)方法該怎么用

import {createStore} from "redux";

//給初始狀態(tài)一個(gè)默認(rèn)值:{money: 0}
function reducer(state = {money: 0}, action) {
    //返回一個(gè)新的state可以使用es6提供的Object.assign()方法,或擴(kuò)展運(yùn)算符(此方法需要babel-preset-state-3支持)
    switch (action.type) {
        case "+":
            return Object.assign({}, state, {money: state.money + 1});
        case "-":
            return {...state, ...{money: state.money - 1}};
        default:
            return state;
    }
}

//action創(chuàng)建函數(shù),返回了一個(gè)action
function add() {
    return {type: "+"}
}

function subtraction() {
    return {type: "-"}
}

//創(chuàng)建單一狀態(tài)樹
const store = createStore(reducer);

console.log(store.getState());//{money: 0},初始的狀態(tài),沒有任何改變(通過getState來獲取目前的狀態(tài))

//store通過dispatch這個(gè)方法,并且傳入action作為參數(shù),對(duì)store進(jìn)行了改變
store.dispatch(add());
console.log(store.getState());//{money: 1},reducer接受到了 "+" 這個(gè)命令,就撿到了一塊錢

store.dispatch(subtraction());
console.log(store.getState());//{money: 0},reducer接受到了 "-" 這個(gè)命令,又掉了一塊錢

store.dispatch({type:"我是來?yè)v亂的"});
console.log(store.getState());//{money: 0},reducer接受到了一個(gè)不識(shí)別命令,返回原有的state

這個(gè)時(shí)候我們就會(huì)發(fā)現(xiàn)幾個(gè)問題:

每次狀態(tài)改變的時(shí)候我們都要console.log()才能知道改變后的狀態(tài),

action的type實(shí)際上就是一個(gè)字符串,如果我們需要進(jìn)行項(xiàng)目維護(hù),更改type的值,就需要在多處進(jìn)行修改,變得十分麻煩。

這個(gè)時(shí)候我們就可以使用store.subscribe()來訂閱一個(gè)事件,代替我們?cè)诿看?b>dispatch后都要console.log()后才能知道改變后的狀態(tài)

function listen() {
    console.log(store.getState());
}

store.subscribe(listen);

將type維護(hù)成常量,這樣我們?cè)谌蘸蟮木S護(hù)過程中只需要對(duì)常量進(jìn)行維護(hù)就可以了,我們目前這個(gè)demo使用到type的地方太少可能感覺不到,可是在實(shí)際項(xiàng)目中這個(gè)方法卻非常的實(shí)用

const ADD = "+", SUBTRACTION = "-";

我們優(yōu)化后的代碼如下:

import {createStore} from "redux";

//定義常量方便維護(hù)
const ADD = "+", SUBTRACTION = "-";

//給初始狀態(tài)一個(gè)默認(rèn)值:{money: 0}
function reducer(state = {money: 0}, action) {
    //返回一個(gè)新的state可以使用es6提供的Object.assign()方法,或擴(kuò)展運(yùn)算符(此方法需要babel-preset-state-3支持)
    switch (action.type) {
        case ADD:
            return Object.assign({}, state, {money: state.money + 1});
        case SUBTRACTION:
            return {...state, ...{money: state.money - 1}};
        default:
            return state;
    }
}

//action創(chuàng)建函數(shù),返回了一個(gè)action
function add() {
    return {type: ADD}
}

function subtraction() {
    return {type: SUBTRACTION}
}

//打印改變后的狀態(tài)
function listen() {
    console.log(store.getState());
}

//創(chuàng)建單一狀態(tài)樹
const store = createStore(reducer);

//訂閱listen,每次dispatch后都會(huì)執(zhí)行l(wèi)isten,從而打印狀態(tài)(只有在執(zhí)行dispatch后才會(huì)執(zhí)行,狀態(tài)初始化的時(shí)候并不會(huì)執(zhí)行)
store.subscribe(listen);

console.log(store.getState());//初始的狀態(tài),沒有任何改變

//store通過dispatch這個(gè)方法,并且傳入action作為參數(shù),對(duì)store進(jìn)行了改變
store.dispatch(add());
store.dispatch(subtraction());
store.dispatch({type: "我是來?yè)v亂的"});

/*控制臺(tái)的打印結(jié)果如下:
{money: 0}
{money: 1}
{money: 0}
{money: 0}*/

補(bǔ)充:
一個(gè)應(yīng)用只能有一個(gè)store,這個(gè)時(shí)候就會(huì)有一個(gè)問題 ,如果有多個(gè)reducer分別來處理不同的狀態(tài),而createStore是能接受一個(gè)reducer,這個(gè)時(shí)候我們就需要redux提供的combineReducers方法來將多個(gè)reducer結(jié)合成一個(gè)reducer

import {combineReducers} from "redux";

const reducerFamily=combineReducers({
    reduceSon,
    reduceDaughter,
    reducerFather,
    reducerMother
})
const store = createStore(reducerFamily);
二.在React中使用redux

如果會(huì)react,那么也一定知道creact-react-app這個(gè)官方腳手架工具,首先使用creact-react-app創(chuàng)建一個(gè)項(xiàng)目,然后刪除src目錄下所有文件,接下來就可以愉快的敲代碼了。

在src下創(chuàng)建三個(gè)文件
index.js

import React from "react"
import ReactDOM from "react-dom"
import {createStore} from "redux"
//引入我們的reducer和action創(chuàng)建函數(shù)
import {reducer, add, subtraction} from "./index.redux"
import App from "./App"

//創(chuàng)建store
const store = createStore(reducer);

//store.subscribe方法接受的參數(shù)是一個(gè)函數(shù),
// 所以將ReactDOM.render方法寫在一個(gè)函數(shù)內(nèi)
function listen() {
    //將store,action創(chuàng)建函數(shù)分別以屬性的方式傳遞給子組件App
    ReactDOM.render(,
        document.querySelector("#root"));
}

//因?yàn)閯傔M(jìn)入頁(yè)面沒有dispatch操作改變store,
// 所以listen不會(huì)執(zhí)行,我們需要手動(dòng)調(diào)用一次
listen();

//重點(diǎn),改變了store,頁(yè)面就會(huì)重新渲染,
// 可以試試不寫這行代碼會(huì)是怎樣的效果
store.subscribe(listen);

App.js

import React from "react"

export default class App extends React.Component {
    render() {
        //從屬性中獲取store,action創(chuàng)建函數(shù)
        const {store, add, subtraction} = this.props;
        //獲取state
        let state = store.getState();
        return 

我有{state.money}元

{/*通過store.dispatch方法改變store,從而頁(yè)面也會(huì)改變*/}
} }

index.redux.js

//定義常量方便維護(hù)
const ADD = "+", SUBTRACTION = "-";

//給初始狀態(tài)一個(gè)默認(rèn)值:{money: 0}
export function reducer(state = {money: 0}, action) {
    //返回一個(gè)新的state可以使用es6提供的Object.assign()方法,或擴(kuò)展運(yùn)算符(此方法需要babel-preset-state-3支持)
    switch (action.type) {
        case ADD:
            return Object.assign({}, state, {money: state.money + 1});
        case SUBTRACTION:
            return {...state, ...{money: state.money - 1}};
        default:
            return state;
    }
}

//action創(chuàng)建函數(shù),返回了一個(gè)action
export function add() {
    return {type: ADD}
}

export function subtraction() {
    return {type: SUBTRACTION}
}

效果圖

這樣我們就將redux和react結(jié)合了起來但是這樣我們可能會(huì)覺得麻煩,因?yàn)槲覀円獙tore和action創(chuàng)建函數(shù)傳給子組件,當(dāng)我們的action比較多時(shí),子組件比較多時(shí),就需要將store和大量的action創(chuàng)建函數(shù)一層層的多次傳遞下去。這樣就會(huì)十分麻煩,因此我們就可以使用react-redux這個(gè)庫(kù)來幫助我們實(shí)現(xiàn)這個(gè)麻煩的過程

三.react-redux的使用 1.Provider

react-redux給我們提供了一個(gè)Provider組件,我們可以把這個(gè)組件寫在最外層,這樣被Provider包裹的所有組件都可以通過props來獲取state,無論組個(gè)組件藏得多么深。
Provider組件只接受一個(gè)屬性,那就是store

那么我們index.js的代碼就變成下面這樣了:

import React from "react"
import ReactDOM from "react-dom"
import {createStore} from "redux"
import {Provider} from "react-redux"
import {reducer} from "./index.redux"
import App from "./App"

//創(chuàng)建store
const store = createStore(reducer);

ReactDOM.render(
    
        
    ,
    document.querySelector("#root"));
2.connect

當(dāng)然,只有Provider組件是不夠的,我們還需要connect來幫助我們獲取state和action,沒錯(cuò),connect就是幫助我們獲取state和action的

那么問題就來了,我們的組件可不是需要項(xiàng)目中所有的state和action,只需要其中的一部分就可以了,所以connect會(huì)接受兩個(gè)參數(shù),第一個(gè)參數(shù)它可以幫我們篩選state,第二個(gè)參數(shù)可以幫我們篩選action。
我們可以把這兩個(gè)參數(shù)寫成函數(shù)的形式,
參數(shù)1,

function mapStateToProps(state) {
    return {
        money: state.money
    }
}

參數(shù)2,

function actionCreators() {
    return {
        subtraction,
        add
    }
}

我們可以發(fā)現(xiàn)這兩個(gè)函數(shù)都是返回了一個(gè)對(duì)象,第一個(gè)函數(shù)返回了我們需要的state,第二個(gè)函數(shù)返回了我們需要的action創(chuàng)建函數(shù)

那么app.js 的代碼就變成這樣了:

import React from "react"
import {connect} from "react-redux"
import {add, subtraction} from "./index.redux"

class App extends React.Component {
    render() {
        //因?yàn)閏onnect的原因,state和action我們已經(jīng)可以從屬性中獲取了
        const {money, add, subtraction} = this.props;

        return 

我有{money}元

{/*這個(gè)時(shí)候不需要我們dispatch了*/}
} } //connect所需要的參數(shù) //函數(shù)返回的我們需要的狀態(tài),我們需要money,就從state中取出money //假如我們還需要house,就增加一個(gè)house:state.house function mapStateToProps(state) { return { money: state.money } } //connect需要的第二參數(shù) //返回我們需要的action創(chuàng)建函數(shù) function actionCreators() { return { subtraction, add } } //上面兩個(gè)函數(shù)返回的都是對(duì)象 //通過connect將state和action創(chuàng)建函數(shù)當(dāng)做屬性傳遞給組件 export default App = connect(mapStateToProps, actionCreators())(App);

如果熟悉es6裝飾器的語(yǔ)法那就更好了,可以使我們的代碼變得更優(yōu)雅
app.js

import React from "react"
import {connect} from "react-redux"
import {add, subtraction} from "./index.redux"

@connect(
    state => ({money: state.money}),
    {
        subtraction,
        add
    })
export default class App extends React.Component {
    render() {
        //因?yàn)閏onnect的原因,state和action我們已經(jīng)可以從屬性中獲取了
        const {money, add, subtraction} = this.props;

        return 

我有{money}元

{/*這個(gè)時(shí)候不需要我們dispatch了*/}
} }

看到這里再回頭看看最開始圖片,就能搞清楚redux的工作流程究竟是怎樣的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105959.html

相關(guān)文章

  • Redux原理分析

    摘要:調(diào)用鏈中最后一個(gè)會(huì)接受真實(shí)的的方法作為參數(shù),并借此結(jié)束調(diào)用鏈。總結(jié)我們常用的一般是除了和之外的方法,那個(gè)理解明白了,對(duì)于以后出現(xiàn)的問題會(huì)有很大幫助,本文只是針對(duì)最基礎(chǔ)的進(jìn)行解析,之后有機(jī)會(huì)繼續(xù)解析對(duì)他的封裝 前言 雖然一直使用redux+react-redux,但是并沒有真正去講redux最基礎(chǔ)的部分理解透徹,我覺得理解明白redux會(huì)對(duì)react-redux有一個(gè)透徹的理解。 其實(shí),...

    sumory 評(píng)論0 收藏0
  • redux原理分析

    摘要:介紹是一個(gè)針對(duì)應(yīng)用的可預(yù)測(cè)的狀態(tài)管理器。中的設(shè)計(jì)模式裝飾者模式定義裝飾者模式用于給對(duì)象動(dòng)態(tài)地增加職責(zé)。連接操作不會(huì)改變?cè)瓉淼慕M件類,而是返回一個(gè)新的已與連接的組件類。的這行代碼表示它對(duì)的數(shù)據(jù)進(jìn)行訂閱。 redux介紹 redux是一個(gè)針對(duì)JavaScript應(yīng)用的可預(yù)測(cè)的狀態(tài)管理器。 redux中的設(shè)計(jì)模式 裝飾者模式 定義:裝飾者模式用于給對(duì)象動(dòng)態(tài)地增加職責(zé)。 我們來看看redux最...

    jubincn 評(píng)論0 收藏0
  • 【源碼解析】redux-thunk

    摘要:的返回值是函數(shù),這個(gè)函數(shù)經(jīng)調(diào)用,傳入?yún)?shù),之后會(huì)在中間件鏈上進(jìn)行傳遞,只要保證每個(gè)中間件的參數(shù)是并且將傳遞給下一個(gè)中間件。 了解了Redux原理之后,我很好奇Redux中間件是怎么運(yùn)作的,于是選了最常用的redux-thunk進(jìn)行源碼分析。 此次分析用的redux-thunk源碼版本是2.2.0,redux源碼版本是3.7.2。并且需要了解Redux原理 redux中間件都是由redu...

    simpleapples 評(píng)論0 收藏0
  • redux源碼分析

    摘要:背景如今在如此復(fù)雜的前端交互和邏輯中,如果是單靠框架,,是遠(yuǎn)遠(yuǎn)不夠的,還需要一個(gè)對(duì)內(nèi)部的數(shù)據(jù)狀態(tài)進(jìn)行管理的機(jī)制才行,而對(duì)于這種數(shù)據(jù)管理機(jī)制如今較為熱門是主要有幾個(gè),,這次主要講述的就是對(duì)源碼進(jìn)行分析。 由于這段時(shí)間一直很忙,所以本想六月初研究完redux源碼就寫一篇博客記錄一下自己的心得,但一直現(xiàn)在才空閑出來,廢話不多說了,直接說主題吧。 背景:如今在如此復(fù)雜的前端交互和邏輯中,如果是...

    Sike 評(píng)論0 收藏0
  • 基于react+react-router+redux+socket.io+koa開發(fā)一個(gè)聊天室

    摘要:最近練手開發(fā)了一個(gè)項(xiàng)目,是一個(gè)聊天室應(yīng)用。由于我們的項(xiàng)目是一個(gè)單頁(yè)面應(yīng)用,因此只需要統(tǒng)一打包出一個(gè)和一個(gè)。而就是基于實(shí)現(xiàn)的一套基于事件訂閱與發(fā)布的通信庫(kù)。比如說,某一個(gè)端口了,而如果端口訂閱了,那么在端,對(duì)應(yīng)的回調(diào)函數(shù)就會(huì)被執(zhí)行。 最近練手開發(fā)了一個(gè)項(xiàng)目,是一個(gè)聊天室應(yīng)用。項(xiàng)目雖不大,但是使用到了react, react-router, redux, socket.io,后端開發(fā)使用了...

    NusterCache 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<