成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

快速理解react-redux

MoAir / 3349人閱讀

摘要:和的結(jié)合簡述相信很多前端開發(fā)者都聽說或使用過,我曾寫過一篇關(guān)于快速理解的文章,雖說是快速理解,但實(shí)際上更應(yīng)該叫做復(fù)習(xí)吧。它通過高階函數(shù),純函數(shù)使我們在編寫組件時(shí)完全不用接觸相關(guān)內(nèi)容,只通過將組件和數(shù)據(jù)連接起來即可。

react-redux react和redux的結(jié)合 簡述

相信很多前端開發(fā)者都聽說或使用過react-redux,我曾寫過一篇關(guān)于快速理解redux的文章,雖說是快速理解,但實(shí)際上更應(yīng)該叫做復(fù)習(xí)redux吧。本文也只是講述react-redux的思想及原理,對于細(xì)節(jié)實(shí)現(xiàn)則不贅述。

一、初始化工程

我們先create-react-app新建一個(gè)react項(xiàng)目,然后安裝第三方庫cnpm install --save prop-types

我們在src目錄下新建3個(gè)文件,Header.js、Content.js、ThemeSwitch.js

組件結(jié)構(gòu)是這樣的

運(yùn)行起來是這樣的

二、結(jié)合context和store

我們先構(gòu)建store,并且把它放在Index組件的context里面,那樣Index以下的所有組件都可以使用store了。

  class Index extends Component {
  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return { store }
  }

  render () {
    return (
      
) } }

我們修改Header,Content,ThemeSwitch,定義一個(gè)函_updateThemeColor在componentWillMount中調(diào)用

在該函數(shù)中獲取Index組件context里的store,并且將store里的colorState這只為自己文本的顏色

我們再修改ThemeSwitch,使按鈕綁定事件,點(diǎn)擊后執(zhí)行dispatch修改store里的state

此時(shí)我們點(diǎn)擊按鈕后,store里的數(shù)據(jù)確實(shí)改變了,可是頁面卻沒有改變,為何?

因?yàn)槲覀兒雎粤藄ubscribe,使得dispatch后_updateThemeColor函數(shù)并未執(zhí)行

我們分別給 Header.js、Content.js、ThemeSwitch.js 的 componentWillMount 生命周期都加上監(jiān)聽數(shù)據(jù)變化重新渲染的代碼

代碼如下,僅以ThemeSwitch為例,其他文件類似

class ThemeSwitch extends Component {
  static contextTypes = {
    store: PropTypes.object
  }

  constructor () {
    super()
    this.state = { themeColor: "" }
  }

  componentWillMount () {
    const { store } = this.context
    this._updateThemeColor()
    store.subscribe(() => this._updateThemeColor())
  }

  _updateThemeColor () {
    const { store } = this.context
    const state = store.getState()
    this.setState({ themeColor: state.themeColor })
  }

  // dispatch action 去改變顏色
  handleSwitchColor (color) {
    const { store } = this.context
    store.dispatch({
      type: "CHANGE_COLOR",
      themeColor: color
    })
  }

  render () {
    return (
      
) } }

到這里,我們已經(jīng)把react-redux的骨架搭建起來了

三、connect 和 mapStateToProps

我們觀察剛剛寫的組件,他們存在兩個(gè)問題

有大量重復(fù)邏輯

使用Connect高階組件解決

對context依賴過強(qiáng),可復(fù)用性過低

使用mapStateToProps解決

使用高階組件

我們需要高階組件幫助我們從 context 取數(shù)據(jù),我們也需要寫 Dumb(純) 組件幫助我們提高組件的復(fù)用性。所以我們盡量多地寫 Dumb 組件,然后用高階組件把它們包裝一層,高階組件和 context 打交道,把里面數(shù)據(jù)取出來通過 props 傳給 Dumb 組件。

這個(gè)高階組件被其銘文Connect,因?yàn)樗梢园?Dunb組件context數(shù)據(jù) connect 起來

import React, { Component } from "react"
import PropTypes from "prop-types"

export const connect = (mapStateToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    render () {
      const { store } = this.context
      let stateProps = mapStateToProps(store.getState())
      // {...stateProps} 意思是把這個(gè)對象里面的屬性全部通過 `props` 方式傳遞進(jìn)去
      return 
    }
  }

  return Connect
}

我們將新建一個(gè)react-redux文件,將Connect放進(jìn)去
我們在定義 mapStateToProps函數(shù) 使它接收某參數(shù),返回相應(yīng)的數(shù)據(jù)。因?yàn)?strong>不同的組件需要store中不同的數(shù)據(jù)

import React, { Component } from "react"
import PropTypes from "prop-types"
import { connect } from "./react-redux"

class Header extends Component {
  static propTypes = {
    themeColor: PropTypes.string
  }

  render () {
    return (
      

React.js 小書

) } } const mapStateToProps = (state) => { return { themeColor: state.themeColor } } Header = connect(mapStateToProps)(Header) export default Header

此時(shí),Header 刪掉了大部分關(guān)于 context 的代碼,它除了 props 什么也不依賴,它是一個(gè) Pure Component,然后通過 connect 取得數(shù)據(jù)。我們不需要知道 connect 是怎么和 context 打交道的,只要傳一個(gè) mapStateToProps 告訴它應(yīng)該怎么取數(shù)據(jù)就可以了。
此時(shí),Connect還未能監(jiān)聽渲染,我們需要在Connect中創(chuàng)建渲染函數(shù)并且在componentWillMount中添加渲染函數(shù)

  export const connect = (mapStateToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = { allProps: {} }
    }

    componentWillMount () {
      const { store } = this.context
      this._updateProps()
      store.subscribe(() => this._updateProps())
    }

    _updateProps () {
      const { store } = this.context
      let stateProps = mapStateToProps(store.getState(), this.props) // 額外傳入 props,讓獲取數(shù)據(jù)更加靈活方便
      this.setState({
        allProps: { // 整合普通的 props 和從 state 生成的 props
          ...stateProps,
          ...this.props
        }
      })
    }

    render () {
      return 
    }
  }

  return Connect
}

現(xiàn)在已經(jīng)很不錯(cuò)了,Header.js 和 Content.js 的代碼都大大減少了,并且這兩個(gè)組件 connect 之前都是 Dumb 組件。接下來會(huì)繼續(xù)重構(gòu) ThemeSwitch。

mapDispatchToProps

到目前為止,我們每次在更改數(shù)據(jù)時(shí),都要用過store.dispatch修改。
為了使組件更 Dunb(純) 我們對Connect和ThemeSwitch增加一個(gè)mapDispatchToProps 函數(shù),使ThemeSwitch組件擺脫對store.dispatch的依賴

export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = {
        allProps: {}
      }
    }

    componentWillMount () {
      const { store } = this.context
      this._updateProps()
      store.subscribe(() => this._updateProps())
    }

    _updateProps () {
      const { store } = this.context
      let stateProps = mapStateToProps
        ? mapStateToProps(store.getState(), this.props)
        : {} // 防止 mapStateToProps 沒有傳入
      let dispatchProps = mapDispatchToProps
        ? mapDispatchToProps(store.dispatch, this.props)
        : {} // 防止 mapDispatchToProps 沒有傳入
      this.setState({
        allProps: {
          ...stateProps,
          ...dispatchProps,
          ...this.props
        }
      })
    }

    render () {
      return 
    }
  }
  return Connect
}
import React, { Component } from "react"
import PropTypes from "prop-types"
import { connect } from "./react-redux"

class ThemeSwitch extends Component {
  static propTypes = {
    themeColor: PropTypes.string,
    onSwitchColor: PropTypes.func
  }

  handleSwitchColor (color) {
    if (this.props.onSwitchColor) {
      this.props.onSwitchColor(color)
    }
  }

  render () {
    return (
      
) } } const mapStateToProps = (state) => { return { themeColor: state.themeColor } } const mapDispatchToProps = (dispatch) => { return { onSwitchColor: (color) => { dispatch({ type: "CHANGE_COLOR", themeColor: color }) } } } ThemeSwitch = connect(mapStateToProps, mapDispatchToProps)(ThemeSwitch) export default ThemeSwitch

光看 ThemeSwitch 內(nèi)部,是非常清爽干凈的,只依賴外界傳進(jìn)來的 themeColor 和 onSwitchColor。但是 ThemeSwitch 內(nèi)部并不知道這兩個(gè)參數(shù)其實(shí)都是我們?nèi)?store 里面取的,它是 Dumb 的。

五、Provider

我們要把所有和context有關(guān)的東西都分離出去,現(xiàn)在只有Index組件是被污染的
所以,我們在react-redux中新增Provider類,讓它包裹成為Index的高階函數(shù),包裹index
使組件結(jié)構(gòu)圖如下

代碼如下

export class Provider extends Component {
  static propTypes = {
    store: PropTypes.object,
    children: PropTypes.any
  }

  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return {
      store: this.props.store
    }
  }

  render () {
    return (
      
{this.props.children}
) } }
...
// 頭部引入 Provider
import { Provider } from "./react-redux"
...

// 刪除 Index 里面所有關(guān)于 context 的代碼
class Index extends Component {
  render () {
    return (
      
) } } // 把 Provider 作為組件樹的根節(jié)點(diǎn) ReactDOM.render( , document.getElementById("root") )

此時(shí),我們就把所有關(guān)于 context 的代碼從組件里面刪除了。

六、react-redux總結(jié)

redux的思想就是有條理地,有規(guī)則地修改共享數(shù)據(jù)。而react里剛好有 context 這個(gè)東西可以被某組件以下的所有組件共享,為了在react中優(yōu)雅的修改context,react-redux就誕生了。它通過高階函數(shù)(Connect),純函數(shù)(mapStateToProps, mapDispatchToProps) 使我們在編寫組件時(shí)完全不用接觸context相關(guān)內(nèi)容,只通過ConnectDumb組件Context數(shù)據(jù) 連接起來即可。

參考

react小書

完整代碼

make-react-redux

本文如果有錯(cuò),歡迎指出

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100241.html

相關(guān)文章

  • react-redux 開發(fā)實(shí)踐與學(xué)習(xí)分享

    摘要:簡介是一個(gè)狀態(tài)管理的庫,由基礎(chǔ)上開發(fā)出來,與的主要區(qū)別是只有一個(gè),關(guān)于,后文會(huì)詳述。這個(gè)函數(shù)接受四個(gè)參數(shù),它們分別是,,和。之前在注冊頁面,如果沒有滿足相關(guān)條件,則觸發(fā)的行為。具體定義了項(xiàng)目中觸發(fā)的行為類別,通過屬性來區(qū)別于不同的行為。 redux簡介 redux是一個(gè)js狀態(tài)管理的庫,由flux基礎(chǔ)上開發(fā)出來,與flux的主要區(qū)別是只有一個(gè)store,關(guān)于store,后文會(huì)詳述。在各...

    imccl 評(píng)論0 收藏0
  • React-Redux 中文文檔

    摘要:介紹快速開始是的官方綁定庫。通常你可以以下面這種方式調(diào)用方法基礎(chǔ)教程為了進(jìn)一步了解如何實(shí)際使用,我們將一步一步創(chuàng)建一個(gè)一個(gè)實(shí)例跳轉(zhuǎn)到 介紹 快速開始 React-Redux是Redux的官方React綁定庫。它能夠使你的React組件從Redux store中讀取數(shù)據(jù),并且向store分發(fā)actions以更新數(shù)據(jù) 安裝 在你的React app中使用React-Redux: npm i...

    MobService 評(píng)論0 收藏0
  • react-redux初探理解

    摘要:它的作用就是像它的名字那樣,建立一個(gè)從外部的對象到組件的對象的映射關(guān)系。比如表示從整個(gè)的表示當(dāng)前組件容器的用來建立組件的參數(shù)到方法的映射比如表示它定義了哪些用戶的操作應(yīng)該當(dāng)作,傳給。 最近做的項(xiàng)目加入了react-redux,對react-redux一直沒理解透徹,最近有時(shí)間把react-redux梳理了一番,希望能夠幫助到大家, 首先有這幾個(gè)文件,action,reducer,sag...

    ziwenxie 評(píng)論0 收藏0
  • React專題:react,redux以及react-redux常見一些面試題

    摘要:我們可以為元素添加屬性然后在回調(diào)函數(shù)中接受該元素在樹中的句柄,該值會(huì)作為回調(diào)函數(shù)的第一個(gè)參數(shù)返回。使用最常見的用法就是傳入一個(gè)對象。單向數(shù)據(jù)流,比較有序,有便于管理,它隨著視圖庫的開發(fā)而被概念化。 面試中問框架,經(jīng)常會(huì)問到一些原理性的東西,明明一直在用,也知道怎么用, 但面試時(shí)卻答不上來,也是挺尷尬的,就干脆把react相關(guān)的問題查了下資料,再按自己的理解整理了下這些答案。 reac...

    darcrand 評(píng)論0 收藏0
  • React-redux中connect方法的理解

    摘要:應(yīng)用中唯一的狀態(tài)應(yīng)用的子組件例子方法來看下函數(shù)到底是如何將和組件聯(lián)系在一起的,注意到文檔中有這樣的一句話并不會(huì)改變它連接的組件,而是提供一個(gè)經(jīng)過包裹的組件。 關(guān)于React-redux Redux是React全家桶的重要一員,之前在知乎上也看到類似的提問:該如何通俗易懂的理解Redux? Redux是JavaScript的狀態(tài)容器,Redux的概念簡單明了: 1. 應(yīng)用中所有的狀...

    Bryan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<