前言 : 今天呢,就配置一下redux,redux的重要性呢,就叭叭叭一大堆,什麼也沒有帶着配置一次來的重要,由於許多涉及到的屬性和方法,用法是活的,但格式是須要記憶的。css
過程當中不要嫌我嘮叨,有的地方爲了便於理解和記憶,反而會繞一下,配置redux的確比較麻煩,用到咱們平時不經常使用的方法,咱們不熟悉他們,因此會使用過程須要記憶。react
(1)首先呢,安裝redux環境npm
一個穩定版的redux和一個redux綁定庫redux
1 npm install redux --save 2 npm install react-redux --save
本行代碼純屬友情贈送,看到了就是賺到了,一個redux開發者工具ide
npm install redux-devtools --save-dev
是在這裏用滴:函數
而後咱們檢查package,已經完成。工具
(2)如今呢,感覺這3個重要的概念action,reducer以及store。this
一、用Action來分辨具體的執行動做。好比我是要添加一個項目仍是刪除一個項目。spa
二、操做數據首先得有數據。好比添加數據得有數據,刪除數據得有ID。action就是存這些數據的地方。3d
三、不帶其餘數據,僅僅啓示已有數據須要如何調整,或者須要主動獲取哪些數據。若是我要刪除掉所有數據,只要告知這件事便可
官方描述:Action 只是描述了有事情發生了這一事實,並無指明應用如何更新 state。這是 reducer 要作的事情。
這麼說吧,Action就像一個指揮者,告訴咱們應該作哪些事,好比我要刪除,reducer就會給咱們提供‘資源(就是上面說的數據)’,真正的體力勞動者是reducer。
也就是說,action裏面的每一種描述,好比新增啦,刪除一個,刪除所有啦,reducer都有一個對應的函數來處理數據。以後返回給你一個新的state
reducer 只是一個模式匹配的東西,真正處理數據的函數,是額外在別的地方寫的,在 reducer 中調用罷了。
※:reducer:縮減 (咱們用來寫方法的)由於 action 對象各類各樣,每種對應某個 case ,但最後都彙總到 state 對象中,從多到一,這是一個減小( reduce )的過程,因此完成這個過程的函數叫 reducer。
前面兩個,咱們知道使用 action 來描述「發生了什麼」,和使用 reducers 來根據 action 更新 state 的用法。
Store 就是把它們聯繫到一塊兒的對象。Store 有如下職責:
(3)接下來建立actions文件夾,再新建一個reducers文件夾,並建立各自的index.js。
建立文件夾不截圖了。。。index先空着,等下補充。
(4)咱們須要將actions和reducers關聯起來(截圖對比代碼,菜鳥請注意)
未修改的src的index.js:
如今呢,從react-redux庫裏,調出Provider方法,從redux裏拿出creatStore方法。
import { Provider } from 'react-redux'; import { creatStore } from 'redux';
React-Redux提供了兩個接口Provider、connect。
Provider 是一個React組件,它的做用是保存store給子組件中的connect使用。
connect 會把State和dispatch轉換成props傳遞給子組件。個人理解是,由於全部的數據都集中在了 store中,Provider從那裏把store的數據拿了過來。給它的好朋友 connect,connect是聯繫,鏈接的意思嘛,因此它將好朋友provider的數據拿了過來,讓它供那些子組件使用。
import rootReducer from "./reducers"
將reducers文件引入(若是是引入文件,默認引入的是index.js)。
咱們建立一個倉庫store:咱們用建立庫方法來以存放應用中全部的 state。
const store = createStore(rootReducer)
用Provider包裹App模塊,而後做爲Hello模塊拋出,在根節點中渲染
const store = createStore(rootReducer) export default class Hello extends Component { render() { return ( <Provider store={ store }> <div> <App/> </div> </Provider> ) } } ReactDOM.render(<Hello />, document.getElementById('root'));
最後的代碼是這個樣子的(運行以後包Component報錯的,注意看圖片上的第一個藍框):
這段代碼的做用,整體上來講應該這樣表述:
我建立了一個Hello模塊來給你們展現redux,建立Hello模塊將App標籤包裹,可是,咱們用Provider組件將return出來的東西包裹,connect方法生成容器組件之後,須要讓容器組件拿到state對象,才能生成 UI 組件的參數。這樣,App的全部子組件就默認均可以拿到state了。同時,咱們直接渲染到root根節點的App也就改爲了Hello。
(5)接下來配置reducers的index.js
在這個index裏,咱們要作的,就是將裏面全部的小的reducers整合起來,而後拋出。我這裏假設用page01和page02來分開管理小的reducers,固然,你不嫌麻煩能夠把全部的功能都寫在主文件裏。
個人page1和2裏都沒有寫方法,等下再進行功能的編寫。
(6)配置actions裏面的index.js
在這個index,咱們要作的呢,是將全部的方法拋出,也是兩個空的,額,等下就寫。。。
(7)運行調試
此次運行呢,就是看看個人組件能不能正常加載。。。由於你沒仔細看個人index.js裏的第一個藍框,就有可能報這個錯:
其餘錯誤請本身逐漸調試,由於個人已經正常運行。
(8)既然搭建了redux,而後咱們要實現一個方法,點擊自增。。。
(笑噴了本身,這個方法是演示方法中,最經常使用也是最low的demo,本身認爲。。。)
註釋給的很詳細了
(9)配置reducer的counter1
咱們把方法反出去,這裏是把自增的方法反出去了
(10)主組件的一些個操做(兩張圖並一張):
註釋已經很清楚了
mapStateToProps 是一個函數(函數名能夠自定義),它的做用就像它的名字那樣,創建一個從(外部的)state對象到(UI組件的)props對象的映射關係。由此你就能夠推測,mapDispathToProps的意思和這個是差很少的,分發方法。
(11)此時的頁面效果:
我點擊的效果:
恭喜本身,功能實現了。
(12)代碼給大家(index的)
1 import React, { Component } from 'react' 2 3 import './App.css'; 4 5 import { connect } from "react-redux" //從react-redux裏拿到connect方法 6 import { counterCreator } from "./actions" //暴露counterCreator這個方法 7 8 class App extends Component { 9 constructor(props){ 10 super(props) 11 this.state={} 12 } 13 14 handleClick=()=>{ 15 this.props.numAdd() 16 } 17 18 render() { 19 return ( 20 <div className='Box'> 21 <h3>{this.props.$$num}</h3> 22 <button onClick={this.handleClick}>點擊自增</button> 23 </div> 24 ) 25 } 26 } 27 28 //數據 29 const mapStateToProps = (state) => { 30 console.log(state) 31 return { 32 $$num : state.page01.num //$$只是一個標識,建議加 33 } 34 } 35 36 //dispatch 分發方法 37 const mapDispathToProps = (dispatch) => { 38 return{ 39 numAdd : () => dispatch(counterCreator.numAdd()) 40 } 41 } 42 43 //connect 高階組件、高階函數 傳入一個組件=>返回一個新的組件 44 export default connect( 45 mapStateToProps, 46 mapDispathToProps 47 )(App)
感悟:暫時憑本身的知識儲備是配置不了的,但願本身一直進步,學不會的時候,千萬別停下來,戒驕戒躁,加油!