Redux初探

1.安裝

redux是獨(dú)立的數(shù)據(jù)狀態(tài)管理插件,要想和react搭配使用,還需要添加react-redux用來將二者鏈接起來,發(fā)揮其強(qiáng)大作用。

npm install redux react-redux --save

2.創(chuàng)建唯一數(shù)據(jù)中心store

利用redux的createStore創(chuàng)建唯一數(shù)據(jù)中心store,createStore接受reducer為第一個(gè)參數(shù),中間件作為第二個(gè)參數(shù)(此處引用的redux-thunk插件用于擴(kuò)展reducer不僅可以接受action對(duì)象作為參數(shù),同時(shí)還能接受一個(gè)函數(shù)作為參數(shù),由此實(shí)現(xiàn)在action中實(shí)現(xiàn)異步請(qǐng)求)。

subscribe 這個(gè)函數(shù)是用來去訂閱 store 的變化,比如你每次對(duì) store 進(jìn)行 dispatch(action) 都會(huì)觸發(fā) subscribe 注冊(cè)的函數(shù)調(diào)用,這個(gè)在實(shí)際情況不是必須要的,看自己的應(yīng)用場景,比如你想監(jiān)控 store 的全局變化時(shí) 可以用 subscript 訂閱一下,然后作一些反應(yīng)。

import { createStore, applyMiddleware } from 'redux';
import reducers from '../reducers/index'
import thunk from 'redux-thunk'

let store = createStore(reducers, applyMiddleware(thunk));

// 可以手動(dòng)訂閱更新,也可以事件綁定到視圖層。
store.subscribe(() =>
  console.log(store.getState())
);

export default store;

3.修改store內(nèi)數(shù)據(jù)的唯一動(dòng)作提交action

要想修改store內(nèi)的數(shù)據(jù)唯一方法就是提交action,action是一個(gè)帶有tyoe屬性的對(duì)象,其他屬性可以任意填寫。編寫action需要注意幾點(diǎn):

  • 單獨(dú)存儲(chǔ)action的type,避免不必要的無提示的錯(cuò)誤編寫;
  • 通過函數(shù)創(chuàng)建action,前面我們說過,引入了redux-thunk插件,他允許action返回一個(gè)函數(shù)作為dispatch的對(duì)象,例如actionCreator.js中的getData函數(shù)。
//actionTypes.js
const Types = {
  SET_DATA: 'SET_DATA',
  SET_NORMAL: 'SET_NORMAL',
  SET_LOADING: 'SET_LOADING'
};

export default Types;
// actionCreator.js
import Types from './actionTypes';

const actionCreator = {
  setLoading: () => {
    return {
      type: Types.SET_LOADING,
      payload : {
        loading: true
      }
    }
  },
  getData: () => {
    return (dispatch, getState) => {
      let action = {
        type: Types.SET_DATA,
        payload: {
          loading: false
        }
      };
      console.log(getState());
      setTimeout(() => {
        dispatch(action);
      }, 3000);
    }
  },
  normal: () => {
    return {
      type: Types.SET_NORMAL,
      payload: {
        count: 4
      }
    }
  }
}

export default actionCreator;

4.神奇的reducer

reducer是唯一可以更改store中數(shù)據(jù)的方法,而且reducer應(yīng)該是一個(gè)沒有任何副作用的純函數(shù),即固定輸入,固定輸出(每次輸入同樣的數(shù)據(jù)都應(yīng)該得到唯一的輸出),這里的副作用值得是setTimeout、異步請(qǐng)求等操作。以下代碼展示了將reducer如何進(jìn)行拆分,利用redux的combineReducers函數(shù),將多個(gè)reducer合并為一個(gè)reducer返回。導(dǎo)出的大reducer作為createStore的第一參數(shù)。

// index.js
import { combineReducers } from 'redux'
import home from './home'
import detail from './detail'

export default combineReducers({
  home,
  detail
});
// reducer 是純函數(shù),輸入固定,輸出固定
// 不能含有任何副作用代碼
import Types from '../actions/actionTypes'
let defaultState = {
  flag: 1,
  loading: false
};
const home = (state = defaultState, action) => {
  switch (action.type) {
    case Types.SET_DATA:
      return Object.assign({}, state, {
        flag: state.flag + 1,
        loading: action.payload.loading
      })
    case Types.SET_LOADING:
      return Object.assign({}, state, {
        loading: action.payload.loading
      })
    case Types.SET_NORMAL:
      return Object.assign({}, state, {
        flag: state.flag + action.payload.count
      })
    default:
      return state;
  }
}

export default home;
//detail.js
let defaultState = {};
const detail = (state = defaultState, action) => {
  switch(action.type){
    default:
      return state;
  }
}

export default detail;

5.react和redux的強(qiáng)力膠水react-redux

react作為視圖層框架,用于管理用戶界面,而redux作為數(shù)據(jù)層框架,用于幾種管理數(shù)據(jù),如何將二者聯(lián)系起來,統(tǒng)一管理數(shù)據(jù),數(shù)據(jù)變動(dòng)觸發(fā)視圖更新呢?答案就是強(qiáng)力膠水react-redux,react-redux利用connect函數(shù)將react視圖組件和store中的數(shù)據(jù)連接起來,具體代碼:

import React, { Component } from 'react';
import { Button } from 'antd';
import { connect } from 'react-redux';
import actionCreator from '../actions/actionCreator';

class TestRedux extends Component {
  handleClick () {
    this.props.setLoading();
    this.props.getData();
  }
  render () {
    return (
      <div>
        <div>{this.props.flag}</div>
        <Button
            onClick={this.handleClick.bind(this)}
            type="primary"
        >增加</Button>
        <Button
            onClick={this.props.getCount}
            type="primary"
        >增加4</Button>
      </div>
    );
  }

}
const mapStateToProps = (state, ownProps) => {
  console.log(ownProps);
  return {
    flag: state.home.flag
  };
};
const mapDispatchToProps = (dispatch, ownProps) => {
  console.log(ownProps);
  return {
    getData () {
      const action = actionCreator.getData();
      dispatch(action);
    },
    getCount () {
      const action = actionCreator.normal();
      dispatch(action);
    }
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(TestRedux);

react-redux的 connect函數(shù)接受兩個(gè)參數(shù)mapStateToProps和mapDispatchToProps,正如兩個(gè)函數(shù)的名字一樣,兩個(gè)函數(shù)返回一個(gè)映射,一個(gè)是state => props的映射,一個(gè)是dispatch => props 的映射,將store中的數(shù)據(jù)映射到對(duì)應(yīng)組件的props屬性上,這樣我們便可以再組件中使用這些屬性。

注意

利用redux-thunk我們返回了getData這個(gè)異步函數(shù)action,細(xì)心的朋友可能已經(jīng)發(fā)現(xiàn),我再組件中映射dispatch時(shí),利用actionCreator創(chuàng)建了getData的action,然后立即dispatch了這個(gè)action,而且在dispatch的這個(gè)函數(shù)中進(jìn)行了異步操作,當(dāng)操作成功后再次調(diào)用dispath,整個(gè)數(shù)據(jù)更新操作中dispath了兩次,我的理解是
1、立即發(fā)出的dispatch用于告知redux,我要更新數(shù)據(jù),但是我現(xiàn)在不更新,你等我下一次通知。
2、異步請(qǐng)求成功后發(fā)出的dispatch就是這個(gè)下一次通知,然后redux相應(yīng)這個(gè)更新,修改store中的數(shù)據(jù)。

結(jié)語

react和redux分管視圖和數(shù)據(jù),實(shí)現(xiàn)了數(shù)據(jù)視圖的真正分離,這是在大型應(yīng)用中很好地,也是易于維護(hù)的,但是任何事情都有利有弊,當(dāng)應(yīng)用逐漸變大,action和reducer的量也會(huì)相應(yīng)變得更加繁瑣,雖然數(shù)據(jù)變化和流轉(zhuǎn)是明確的但是對(duì)于多數(shù)項(xiàng)目來說,還達(dá)不到足夠大,敏捷、高效有時(shí)才是王道,這就是我理解的近年來vue盛行的原因。vue憑借其易學(xué)、易用性迅速崛起。為了解決redux的繁瑣,mobx應(yīng)運(yùn)而生,mobx采用類似vue的響應(yīng)機(jī)制,細(xì)粒度的觀測讓數(shù)據(jù)變化不再這么繁瑣,下節(jié),我們會(huì)剖析mobx的基礎(chǔ)使用,一起學(xué)起來吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄一. 為什么要使用Redux二. Redux是什么?1. Redux的三大組成部分?2. Redux的工作流程...
    意一ineyee閱讀 2,818評(píng)論 1 9
  • 看到這篇文章build an image gallery using redux saga,覺得寫的不錯(cuò),長短也適...
    smartphp閱讀 6,329評(píng)論 1 29
  • 為了幫助大家快速上手什么是Redux開發(fā),在這本節(jié)中將向大家介紹什么是Redux開發(fā)所需要的一些什么是Redux必...
    CrazyCodeBoy閱讀 831評(píng)論 0 2
  • Redux是什么:Redux是一個(gè)專門用來做狀態(tài)管理的JS庫(不是React插件庫)。它可以用在React,Ang...
    BlueSkyBlue閱讀 279評(píng)論 0 1
  • 姓名:鄧寧寧 公司:蔚藍(lán)時(shí)代實(shí)業(yè)有限公司 【日精進(jìn)打卡第296天】 【知-學(xué)習(xí)】 1.大綱0遍 2.大學(xué)0遍 3....
    啊寧_9332閱讀 108評(píng)論 0 0

友情鏈接更多精彩內(nèi)容