国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Redux原理分析

cooxer / 2617人閱讀

摘要:原理分析是什么很多人認為必須要結合使用,其實并不是的,是狀態容器,只要你的項目中使用到了狀態,并且狀態十分復雜,那么你就可以使用管理你的項目狀態,它可以使用在中,也可以使用中在中,當然也適用其他的框架。

Redux原理分析

Redux是什么

很多人認為redux必須要結合React使用,其實并不是的,Redux 是 JavaScript 狀態容器,只要你的項目中使用到了狀態,并且狀態十分復雜,那么你就可以使用Redux管理你的項目狀態,它可以使用在react中,也可以使用中在Vue中,當然也適用其他的框架。
一.redux的工作原理

先上圖(圖片源于網絡)

首先我們找到最上面的state

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

用戶通過一些事件(如點擊按鈕,移動鼠標)就會像reducer派發一個action

reducer接收到action后就會去更新state

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

當然,現在可能看不懂這在瞎說啥,但是等把這篇文章看完再來這個圖,和這段話,就會有恍然大明白的感覺

1.action

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

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

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

function reducer(state = {money: 0}, action) {
    //返回一個新的state可以使用es6提供的Object.assign()方法,或擴展運算符(此方法需要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想成一個狀態樹,它包含了整個redeux應用的所有狀態。
我們使用redux提供的createStore方法生成store

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

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

store.getState();//獲取整個狀態樹
store.dispatch();//改變狀態,改變state的唯一方法
store.subscribe();//訂閱一個函數,每當state改變時,都會去調用這個函數

接下來演示一個redux的完整應用,并且說明這三個方法該怎么用

import {createStore} from "redux";

//給初始狀態一個默認值:{money: 0}
function reducer(state = {money: 0}, action) {
    //返回一個新的state可以使用es6提供的Object.assign()方法,或擴展運算符(此方法需要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創建函數,返回了一個action
function add() {
    return {type: "+"}
}

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

//創建單一狀態樹
const store = createStore(reducer);

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

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

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

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

這個時候我們就會發現幾個問題:

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

action的type實際上就是一個字符串,如果我們需要進行項目維護,更改type的值,就需要在多處進行修改,變得十分麻煩。

這個時候我們就可以使用store.subscribe()來訂閱一個事件,代替我們在每次dispatch后都要console.log()后才能知道改變后的狀態

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

store.subscribe(listen);

將type維護成常量,這樣我們在日后的維護過程中只需要對常量進行維護就可以了,我們目前這個demo使用到type的地方太少可能感覺不到,可是在實際項目中這個方法卻非常的實用

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

我們優化后的代碼如下:

import {createStore} from "redux";

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

//給初始狀態一個默認值:{money: 0}
function reducer(state = {money: 0}, action) {
    //返回一個新的state可以使用es6提供的Object.assign()方法,或擴展運算符(此方法需要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創建函數,返回了一個action
function add() {
    return {type: ADD}
}

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

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

//創建單一狀態樹
const store = createStore(reducer);

//訂閱listen,每次dispatch后都會執行listen,從而打印狀態(只有在執行dispatch后才會執行,狀態初始化的時候并不會執行)
store.subscribe(listen);

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

//store通過dispatch這個方法,并且傳入action作為參數,對store進行了改變
store.dispatch(add());
store.dispatch(subtraction());
store.dispatch({type: "我是來搗亂的"});

/*控制臺的打印結果如下:
{money: 0}
{money: 1}
{money: 0}
{money: 0}*/

補充:
一個應用只能有一個store,這個時候就會有一個問題 ,如果有多個reducer分別來處理不同的狀態,而createStore是能接受一個reducer,這個時候我們就需要redux提供的combineReducers方法來將多個reducer結合成一個reducer

import {combineReducers} from "redux";

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

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

在src下創建三個文件
index.js

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

//創建store
const store = createStore(reducer);

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

//因為剛進入頁面沒有dispatch操作改變store,
// 所以listen不會執行,我們需要手動調用一次
listen();

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

App.js

import React from "react"

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

我有{state.money}元

{/*通過store.dispatch方法改變store,從而頁面也會改變*/}
} }

index.redux.js

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

//給初始狀態一個默認值:{money: 0}
export function reducer(state = {money: 0}, action) {
    //返回一個新的state可以使用es6提供的Object.assign()方法,或擴展運算符(此方法需要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創建函數,返回了一個action
export function add() {
    return {type: ADD}
}

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

效果圖

這樣我們就將redux和react結合了起來但是這樣我們可能會覺得麻煩,因為我們要將store和action創建函數傳給子組件,當我們的action比較多時,子組件比較多時,就需要將store和大量的action創建函數一層層的多次傳遞下去。這樣就會十分麻煩,因此我們就可以使用react-redux這個庫來幫助我們實現這個麻煩的過程

三.react-redux的使用 1.Provider

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

//創建store
const store = createStore(reducer);

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

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

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

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

參數2,

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

我們可以發現這兩個函數都是返回了一個對象,第一個函數返回了我們需要的state,第二個函數返回了我們需要的action創建函數

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

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

class App extends React.Component {
    render() {
        //因為connect的原因,state和action我們已經可以從屬性中獲取了
        const {money, add, subtraction} = this.props;

        return 

我有{money}元

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

如果熟悉es6裝飾器的語法那就更好了,可以使我們的代碼變得更優雅
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() {
        //因為connect的原因,state和action我們已經可以從屬性中獲取了
        const {money, add, subtraction} = this.props;

        return 

我有{money}元

{/*這個時候不需要我們dispatch了*/}
} }

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/105959.html

相關文章

  • Redux原理分析

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

    sumory 評論0 收藏0
  • redux原理分析

    摘要:介紹是一個針對應用的可預測的狀態管理器。中的設計模式裝飾者模式定義裝飾者模式用于給對象動態地增加職責。連接操作不會改變原來的組件類,而是返回一個新的已與連接的組件類。的這行代碼表示它對的數據進行訂閱。 redux介紹 redux是一個針對JavaScript應用的可預測的狀態管理器。 redux中的設計模式 裝飾者模式 定義:裝飾者模式用于給對象動態地增加職責。 我們來看看redux最...

    jubincn 評論0 收藏0
  • 【源碼解析】redux-thunk

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

    simpleapples 評論0 收藏0
  • redux源碼分析

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

    Sike 評論0 收藏0
  • 基于react+react-router+redux+socket.io+koa開發一個聊天室

    摘要:最近練手開發了一個項目,是一個聊天室應用。由于我們的項目是一個單頁面應用,因此只需要統一打包出一個和一個。而就是基于實現的一套基于事件訂閱與發布的通信庫。比如說,某一個端口了,而如果端口訂閱了,那么在端,對應的回調函數就會被執行。 最近練手開發了一個項目,是一個聊天室應用。項目雖不大,但是使用到了react, react-router, redux, socket.io,后端開發使用了...

    NusterCache 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<