React-Redux 學(xué)習(xí)總結(jié)

什么是React-Redux

React-Redux 是Redux 官方出品的,用于配合React的綁定庫(kù)。
說(shuō)到Redux,簡(jiǎn)單來(lái)說(shuō)它就是一個(gè)狀態(tài)管理庫(kù)。在多層組件傳遞props十分繁瑣嗦明,也會(huì)使得組件的數(shù)據(jù)變得非常混亂舍败,但通過(guò)使用Redux招狸,這些問(wèn)題就能得到解決。

想要學(xué)會(huì)使用React-Redux 主要有以下幾個(gè)知識(shí)點(diǎn)需要掌握:

  • 安裝以及起手式
  • 搭建頁(yè)面結(jié)構(gòu)
  • 導(dǎo)入provider組件
  • 組件A發(fā)送 action
  • 組件B接收 action

目標(biāo)效果

我們需要通過(guò)React-Redux完成一個(gè)頁(yè)面邻薯,它有以下內(nèi)容:

  0       <--初始值
【+1按鈕】 <--當(dāng)我們點(diǎn)擊 +1 按鈕 的時(shí)候裙戏,上面的初始值+1

安裝以及起手式

安裝:
創(chuàng)建一個(gè)新的React應(yīng)用的并附帶Redux的時(shí)候:
npx create-react-app react-redux-example

在創(chuàng)建好的React中添加Redux:
npm install redux react-redux

接下來(lái)是起手式:
在src目錄下構(gòu)建 store 和 reducer

構(gòu)建reducer

reducer是一個(gè)純函數(shù),它接收之前的state和action作為參數(shù)厕诡,返回一個(gè)更新了的state累榜。
.src/reducer/index.js,構(gòu)建該文件作為 reducer 來(lái)響應(yīng) actions

//接收兩個(gè)參數(shù)
//第一個(gè)參數(shù)是state
//第二個(gè)參數(shù)是action

//初始數(shù)據(jù)
const initialState = {
  count: 0
}

//reducer要接受action然后進(jìn)行邏輯處理的
//判斷發(fā)送過(guò)來(lái)的action是不是我們而要的
//如果是我們需要的,就應(yīng)該 return一個(gè)新的state了(以對(duì)象的形式)

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case "add_action":
            return { count: state.count + 1}
        default:
            return state
    }
}
export default reducer

構(gòu)建store

store是react項(xiàng)目中存儲(chǔ)state的地方灵嫌,你可以把它看成是一個(gè)大的JavaScript對(duì)象壹罚。創(chuàng)建store時(shí)我們需要一個(gè)reducer來(lái)作為參數(shù),我們已經(jīng)創(chuàng)建好reducer了寿羞,讓我們把它關(guān)聯(lián)到store上面吧猖凛。
.src/store/index.js,通過(guò) createStore 方法 绪穆,把 reducer 傳入

//導(dǎo)入createStore方法
import {createStore} form 'redux'
//導(dǎo)入上面編寫(xiě)好的reducer
import {reducer} form '../reducer'
//構(gòu)建store
export default createStore(reducer)

接下來(lái)需要在 app.js中引入store(這里我提前把App.js的結(jié)構(gòu)寫(xiě)好了辨泳,App組件包裹著CompACompB兩個(gè)組件)
.scr/App.js文件

import React from "react"
import  "./App.css"
// 導(dǎo)入上面構(gòu)建好的store
import store from "./store"
//引入組件A
import CompA from './pages/compA.js'
//引入組件B
import CompA from './pages/compB.js'
function App() {
    return (   
            <div className = "App">
                <CompA/>
                <CompB/>
            </div>
    )
}
export default App

搭建頁(yè)面結(jié)構(gòu)

這里為了演示如何使用Redux 虱岂,我選取了一個(gè)盡量簡(jiǎn)單的頁(yè)面結(jié)構(gòu)案例。
創(chuàng)建頁(yè)面組件A(用來(lái)發(fā)送action)
./src/pages/CompA.js

//里面暫時(shí)先不寫(xiě)東西

創(chuàng)建頁(yè)面組件B(用來(lái)接收A發(fā)出的action)
./src/pages/CompB.js

//里面暫時(shí)也不寫(xiě)東西

好的菠红,到目前為止第岖,我們有了:

  • 一個(gè) reducer,它接收 action 并且進(jìn)行相應(yīng)的處理试溯。
  • 一個(gè) store蔑滓,它通過(guò) redux 的 createStore 方法使用我們上面的reducer來(lái)構(gòu)建一個(gè)store。
  • 一個(gè) App.js文件遇绞,它導(dǎo)入了上面創(chuàng)建好的 store键袱。并且在它的<App/>組件里面,包裹了2個(gè)子組件摹闽,分別是用來(lái)發(fā)送 action 的 A組件 和用來(lái)接收 action 的 B組件杠纵。

導(dǎo)入provider(把store關(guān)聯(lián)到React)

想把store關(guān)聯(lián)到React,我們需要引入一個(gè)輔助函數(shù)叫做Provider钩骇。然后用Provider組件包裹著App組件,再把store作為props值傳入Provider铝量。
App.js文件中導(dǎo)入provider倘屹,并用它包裹整個(gè)應(yīng)用
還是這個(gè).scr/App.js文件

import React from "react"
import  "./App.css"
// 導(dǎo)入上面構(gòu)建好的store
import store from "./store"

//這里
//這里
//這里
//多了一步導(dǎo)入Provider組件,并且利用它包裹整個(gè)結(jié)構(gòu) 慢叨,從而達(dá)到統(tǒng)一維護(hù)的目的纽匙。
import {Provider} from "react-redux"

//引入組件A
import CompA from './pages/compA.js'
//引入組件B
import CompA from './pages/compB.js'
function App() {
    return (   
            <Provider store = {store}>
            <div className = "App">
                <CompA/>
                <CompB/>
            </div>
        </Provider>
    )
}
export default App

組件A發(fā)送 action

action包含著各種類(lèi)型,比如REMOVE_ARTICLE 或者 ADD_ARTICLE等拍谐。它從react組件中被分發(fā)(傳遞數(shù)據(jù))到redux 的 store 中烛缔。當(dāng)讓action只是一個(gè)傳遞信息的,他不能改變store轩拨。store只能被reducer改變践瓷。
上面的 ./src/pages/CompA.js 編寫(xiě)好之后是這樣子的

class CompA extends React.Component {
    handleClick = () =>{
        //
        this.props.sendAction()
    }
    render() {
        return <button onClick={this.handleClick}> + </button>
    }
}
const mapDispatchToProps = dispatch => {
    return {
        sendAction: () => {
            //利用 dispatch 發(fā)送一個(gè) action
            //傳遞 action 對(duì)象時(shí)需要定義一個(gè) type 屬性
            //返回一個(gè)對(duì)象
            dispatch({
                type: "add_action"
            })
        }
    }
}
// A 是發(fā)送方,所以要實(shí)現(xiàn) connect 第二個(gè)參數(shù)
export default connect(null,mapDispatchToProps)(CompA)

在組件A 里面亡蓉,我們做了這些事情:

  • 導(dǎo)入 connect
  • 利用 connect對(duì)組件進(jìn)行加強(qiáng)
  • 由于A是發(fā)送方晕翠,所以需要實(shí)現(xiàn) connect第二個(gè)參數(shù)
  • 構(gòu)建了一個(gè)函數(shù)mapDispatchToProps(dispatch)
    dispatch就是用來(lái)發(fā)送 action
  • 在上面這個(gè)函數(shù)中就可以返回一個(gè)對(duì)象
    key是方法名 (sendAction)
    value (箭頭函數(shù)):調(diào)用dispatch去發(fā)送action
  • 在組件中的 內(nèi)容就可以通過(guò) this.props來(lái)拿到這個(gè)方法了。

數(shù)據(jù)走到了上面的reducer中

通過(guò)之前的createStore(reducer)

/*
接收2個(gè)參數(shù)
第一個(gè)是 state
第二個(gè)是 action
 */

const initState = {
    count: 0
}
// reducer 要接收 action 然后進(jìn)行邏輯處理
// 它判斷 action 的type 如果是我們需要的砍濒,則執(zhí)行對(duì)應(yīng)的行為 (return 一個(gè)新的state)
const reducer = (state = initState,action) => {
    switch (action.type) {
        case "add_action":
            return {
                count: state.count + 1
            }
        default :
            return state
    }
}
export default reducer

組件B 接收 state

import React from "react";

//導(dǎo)入 connect
import { connect } from "react-redux"

class CompB extends React.Component {
    render() {
        return <div>{this.props.count}</div>
    }
}

//接收兩個(gè)參數(shù)
const mapStateToProps = state => {
    return state
}
//組件B 是接收方淋肾,所以需要實(shí)現(xiàn) connect 方法的第一個(gè)參數(shù)
export  default connect(mapStateToProps)(CompB)

在B組件中,我們做了這些事情:

  • 導(dǎo)入connect方法
  • 利用connect對(duì)組件進(jìn)行加強(qiáng)
  • 組件B是接收方爸邢,所以需要實(shí)現(xiàn) connect方法的第一個(gè)參數(shù)
  • mapStateToProps 里面的第一個(gè)參數(shù)就是我們很關(guān)心的 state
  • 把這個(gè)state進(jìn)行return 才能在組件內(nèi)部獲取到最新的數(shù)據(jù)
  • 組件B 是否能拿到數(shù)據(jù)的關(guān)鍵是 reducer
  • 只有reducer里面返回了新的 state 的時(shí)候樊卓,我們才能獲取到數(shù)據(jù)。

最終顯示效果

  0       <--初始值
【+1按鈕】 <--當(dāng)我們點(diǎn)擊 +1 按鈕 的時(shí)候杠河,上面的初始值+1

流程圖:

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碌尔,一起剝皮案震驚了整個(gè)濱河市浇辜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌七扰,老刑警劉巖奢赂,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異颈走,居然都是意外死亡膳灶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)立由,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轧钓,“玉大人,你說(shuō)我怎么就攤上這事锐膜”瞎浚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵道盏,是天一觀的道長(zhǎng)而柑。 經(jīng)常有香客問(wèn)我,道長(zhǎng)荷逞,這世上最難降的妖魔是什么媒咳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮种远,結(jié)果婚禮上涩澡,老公的妹妹穿的比我還像新娘。我一直安慰自己坠敷,他們只是感情好妙同,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著膝迎,像睡著了一般粥帚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上限次,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天茎辐,我揣著相機(jī)與錄音,去河邊找鬼掂恕。 笑死拖陆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懊亡。 我是一名探鬼主播依啰,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼店枣!你這毒婦竟也來(lái)了速警?” 一聲冷哼從身側(cè)響起叹誉,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闷旧,沒(méi)想到半個(gè)月后长豁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忙灼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年匠襟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片该园。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡酸舍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出里初,到底是詐尸還是另有隱情啃勉,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布双妨,位于F島的核電站淮阐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏刁品。R本人自食惡果不足惜枝嘶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哑诊。 院中可真熱鬧,春花似錦及刻、人聲如沸镀裤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)暑劝。三九已至,卻和暖如春颗搂,著一層夾襖步出監(jiān)牢的瞬間担猛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工丢氢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留傅联,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓疚察,卻偏偏與公主長(zhǎng)得像蒸走,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子貌嫡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容