個人一個配置redux(實現一次存儲與調用方法)之旅

前言 : 今天呢,就配置一下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 做用:

一、用Action來分辨具體的執行動做。好比我是要添加一個項目仍是刪除一個項目。spa

二、操做數據首先得有數據。好比添加數據得有數據,刪除數據得有ID。action就是存這些數據的地方。3d

三、不帶其餘數據,僅僅啓示已有數據須要如何調整,或者須要主動獲取哪些數據。若是我要刪除掉所有數據,只要告知這件事便可

 

Reducer的做用:

官方描述:Action 只是描述了有事情發生了這一事實,並無指明應用如何更新 state。這是 reducer 要作的事情。

這麼說吧,Action就像一個指揮者,告訴咱們應該作哪些事,好比我要刪除,reducer就會給咱們提供‘資源(就是上面說的數據)’,真正的體力勞動者是reducer。

也就是說,action裏面的每一種描述,好比新增啦,刪除一個,刪除所有啦,reducer都有一個對應的函數來處理數據。以後返回給你一個新的state

 reducer 只是一個模式匹配的東西,真正處理數據的函數,是額外在別的地方寫的,在 reducer 中調用罷了。

 ※:reducer:縮減 (咱們用來寫方法的)由於 action 對象各類各樣,每種對應某個 case ,但最後都彙總到 state 對象中,從多到一,這是一個減小( reduce )的過程,因此完成這個過程的函數叫 reducer。

 

Store:

前面兩個,咱們知道使用 action 來描述「發生了什麼」,和使用 reducers 來根據 action 更新 state 的用法。

Store 就是把它們聯繫到一塊兒的對象。Store 有如下職責:

  • 維持應用的 state;
  • 提供 getState() 方法獲取 state;
  • 提供 dispatch(action) 方法更新 state;
  • 經過 subscribe(listener) 註冊監聽器

 

(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提供了兩個接口Providerconnect

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)

 

感悟:暫時憑本身的知識儲備是配置不了的,但願本身一直進步,學不會的時候,千萬別停下來,戒驕戒躁,加油!

相關文章
相關標籤/搜索