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

資訊專欄INFORMATION COLUMN

【React進(jìn)階系列】手寫實(shí)現(xiàn)react-redux api

劉玉平 / 2128人閱讀

簡(jiǎn)介:簡(jiǎn)單實(shí)現(xiàn)react-redux基礎(chǔ)api

react-redux api回顧


把store放在context里,所有子組件可以直接拿到store數(shù)據(jù)

使組件層級(jí)中的 connect() 方法都能夠獲得 Redux store
根組件應(yīng)該嵌套在 
ReactDOM.render(
  
    
  ,
  rootEl
)

ReactDOM.render(
  
    
      
        
        
      
    
  ,
  document.getElementById("root")
)

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
鏈接組件和數(shù)據(jù),把redux中的數(shù)據(jù)放到組件的屬性中

[mapStateToProps(state, [ownProps]): stateProps] (Function)

如果定義該參數(shù),組件將會(huì)監(jiān)聽(tīng) Redux store 的變化。任何時(shí)候,只要 Redux store 發(fā)生改變,mapStateToProps 函數(shù)就會(huì)被調(diào)用。該回調(diào)函數(shù)必須返回一個(gè)純對(duì)象,這個(gè)對(duì)象會(huì)與組件的 props 合并

如果你省略了這個(gè)參數(shù),你的組件將不會(huì)監(jiān)聽(tīng) Redux store
ownProps,則該參數(shù)的值為傳遞到組件的 props,而且只要組件接收到新的 props,mapStateToProps 也會(huì)被調(diào)用,被重新計(jì)算
mapStateToProps 函數(shù)的第一個(gè)參數(shù)是整個(gè)Redux store的state,它返回一個(gè)要作為 props 傳遞的對(duì)象。它通常被稱作 selector (選擇器)。 可以使用reselect去有效地組合選擇器和計(jì)算衍生數(shù)據(jù).
注意:如果定義一個(gè)包含強(qiáng)制性參數(shù)函數(shù)(這個(gè)函數(shù)的長(zhǎng)度為 1)時(shí),ownProps 不會(huì)傳到 mapStateToProps

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}

[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function)

Object: 它的每個(gè)鍵名也是對(duì)應(yīng) UI 組件的同名參數(shù),鍵值應(yīng)該是一個(gè)函數(shù)(action creator),會(huì)被當(dāng)作 Action creator ,返回的 Action 會(huì)由 Redux 自動(dòng)發(fā)出,

Function: 會(huì)得到dispatch和ownProps(容器組件的props對(duì)象)兩個(gè)參數(shù)(此時(shí)可能用到Redux 的輔助函數(shù) bindActionCreators())

省略這個(gè) mapDispatchToProps 參數(shù),默認(rèn)情況下,dispatch 會(huì)注入到你的組件 props 中,你可以this.props.dispatch調(diào)用
指定了該回調(diào)函數(shù)中第二個(gè)參數(shù) ownProps,該參數(shù)的值為傳遞到組件的 props,而且只要組件接收到新 props,mapDispatchToProps 也會(huì)被調(diào)用

eg:

connect(mapStateToProps, {
  hideAdPanel,
  pushAdData,
})(AdPanel)

function mapDispatchToProps(dispatch) {
  return {
    todoActions: bindActionCreators(todoActionCreators, dispatch),
    counterActions: bindActionCreators(counterActionCreators, dispatch)
  }
}
知識(shí)點(diǎn)補(bǔ)充 - React高階組件(Higher-Order Components)

高階組件就是一個(gè)函數(shù),且該函數(shù)接受一個(gè)組件作為參數(shù),并返回一個(gè)新的組件
高階組件就是一個(gè)沒(méi)有副作用的純函數(shù)

使用場(chǎng)景:兩個(gè)組件大部分代碼都是重復(fù)的+且更好的封閉性,不需要關(guān)注數(shù)據(jù)的獲取

import React, {Component} from "react"

class Welcome extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: ""
        }
    }

    componentWillMount() {
        let username = localStorage.getItem("username");
        this.setState({
            username: username
        })
    }

    render() {
        return (
            
welcome {this.state.username}
) } } export default Welcome; import React, {Component} from "react" class Goodbye extends Component { constructor(props) { super(props); this.state = { username: "" } } componentWillMount() { let username = localStorage.getItem("username"); this.setState({ username: username }) } render() { return (
goodbye {this.state.username}
) } } export default Goodbye;

welcome和goodbye組件相似,只能獲取的數(shù)據(jù)不一樣,用高階組件,提取公共部分

import React, {Component} from "react"

export default (WrappedComponent) => {
    class NewComponent extends Component {
        constructor() {
            super();
            this.state = {
                username: ""
            }
        }

        componentWillMount() {
            let username = localStorage.getItem("username");
            this.setState({
                username: username
            })
        }

        render() {
            return 
        }
    }

    return NewComponent
}

簡(jiǎn)化welcome和goodbye

import React, {Component} from "react";
import wrapWithUsername from "wrapWithUsername";

class Welcome extends Component {

    render() {
        return (
            
welcome {this.props.username}
) } } Welcome = wrapWithUsername(Welcome); export default Welcome;

此時(shí),理解react-redux 的connect就好理解了

ConnectedComment = connect(mapStateToProps, mapDispatchToProps)(Component);

// connect是一個(gè)返回函數(shù)的函數(shù)(就是個(gè)高階函數(shù))
const enhance = connect(mapStateToProps, mapDispatchToProps);
// 返回的函數(shù)就是一個(gè)高階組件,該高階組件返回一個(gè)與Redux store
// 關(guān)聯(lián)起來(lái)的新組件
const ConnectedComment = enhance(Component);
provider實(shí)現(xiàn)
import React from "react"
import ReactDOM from "react-dom"
import { createStore, applyMiddleware, compose} from "redux"
import thunk from "redux-thunk"
import { counter } from "./index.redux"
// import { Provider } from "react-redux"
// 換成自己的Provider實(shí)現(xiàn)
import { Provider } from "./self-react-redux"
import App from "./App"

const store = createStore(counter, compose(
  applyMiddleware(thunk),
  window.devToolsExtension ? window.devToolsExtension() : f => f
))
ReactDOM.render(
  (
    
      
    
  ),
  document.getElementById("root"))

./self-react-redux

import React from "react"
import PropTypes from "prop-types"

export function connect(){
}

class Provider extends React.Component{
  static childContextTypes = {
    store: PropTypes.object
  }
  getChildContext() {
    return { store: this.store }
  }
  constructor(props, context) {
    super(props, context)
    this.store = props.store
  }
  render(){
    return this.props.children
  }
}
connect實(shí)現(xiàn)

demo

import React from "react"
// import { connect } from "react-redux"
import { connect } from "./self-react-redux"
import { addGun, removeGun, addGunAsync } from "./index.redux"

@connect(
    // 你要state什么屬性放到props里
    state=>({num:state.counter}),
    // 你要什么方法,放到props里,自動(dòng)dispatch
    { addGun, removeGun, addGunAsync }
)
class App extends React.Component{
    render(){
        return (
            

現(xiàn)在有機(jī)槍{this.props.num}把

) } } export default App

./self-react-redux.js


// 高階組件的寫法
export function connect(maoStateToProps, mapStateToProps) {
  return function(WrapComponent) {
    return class ConnectComponent extends React.Component{
 
    }
  }
}


import React from "react"
import PropTypes from "prop-types"
import { bindActionCreator } from "./self-redux"
// 使用簡(jiǎn)寫形式
// connect負(fù)責(zé)鏈接組件,給到redux里的數(shù)據(jù)放在組件的屬性里
// 1. 負(fù)責(zé)接收一個(gè)組件,把state里的一些數(shù)據(jù)放進(jìn)去,返回一個(gè)組件
// 2. 數(shù)據(jù)變化的時(shí)候,能通知組件
export const connect = (
  mapStateToProps = state => state,
  mapDispatchToProps ={}
) => (WrapComponent) => {
  return class ConnectComponent extends React.Component {
    static contextTypes = {
      store: PropTypes.object
    }
    constructor(props, context){
      super(props, context)
      this.state = {
        props: {}
      }
    } 
    // 2 實(shí)現(xiàn)了mapStateToProps
    componentDidMount() {
      const { store } = this.context
      store.subscribe(() => this.update())
      this.update()
    }
    update() {
      const { store } = this.context
      // store.getState()這就是為什么mapStateToProps函數(shù)里面能拿到state 
      const stateProps = mapStateToProps(store.getState())
      // 方法不能直接給,因?yàn)樾枰猟ispatch
        /**
          function addGun() {
            return { type: ADD_GUN }
          }
          直接執(zhí)行addGun() 毫無(wú)意義
          要 addGun = () => store.dispatch(addGun()) 才有意義,其實(shí)就是把a(bǔ)ctionCreator包了一層
          bindActionCreators在手寫redux api實(shí)現(xiàn)了
         */
      const dispatchProps = bindActionCreators(mapDispatchToProps, store.dispatch)
      // 注意state的順序問(wèn)題會(huì)覆蓋
      this.setState({
        props: {
          ...this.state.props,
          ...stateProps,
          ...dispatchProps,
        }
      })
    }
    // 1
    render() {
      return 
    }
  }
}

./self-redux.js

// creators: {addGun, removeGun, addGunAsync}
// creators[v]:addGun(參數(shù))
// 返回:(參數(shù)) => dispatch(addGun(參數(shù)))
 function bindActionCreator(creator, dispatch) {
   return (...args) => dispatch(creator(...args))
 }

 export function bindActionCreators(creators, dispatch) {
   let bound = {}
   Object.keys(creators).forEach( v => {
     let creator = creators[v]
     bound[v] = bindActionCreator(creator, dispatch)
   })
   return bound
 }
// 簡(jiǎn)寫
 export function bindActionCreators(creators, dispatch) {
  return Object.keys(creators).reduce((ret, item) => {
     ret[item] =  bindActionCreator(creators[item], dispatch)
     return ret
   }, {})
 }

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

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

相關(guān)文章

  • React進(jìn)階系列手寫redux api

    摘要:每個(gè)接受的和函數(shù)作為命名參數(shù),并返回一個(gè)函數(shù)。調(diào)用鏈中最后一個(gè)會(huì)接受真實(shí)的的方法作為參數(shù),并借此結(jié)束調(diào)用鏈。 簡(jiǎn)介: 手寫實(shí)現(xiàn)redux基礎(chǔ)api createStore( )和store相關(guān)方法 api回顧: createStore(reducer, [preloadedState], enhancer) 創(chuàng)建一個(gè) Redux store 來(lái)以存放應(yīng)用中所有的 state reduc...

    Elle 評(píng)論0 收藏0
  • React-redux進(jìn)階之Immutable.js

    摘要:的優(yōu)勢(shì)保證不可變每次通過(guò)操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象豐富的性能好通過(guò)字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享的問(wèn)題與原生交互不友好通過(guò)生成的對(duì)象在操作上與原生不同,如訪問(wèn)屬性,。 Immutable.js Immutable的優(yōu)勢(shì) 1. 保證不可變(每次通過(guò)Immutable.js操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象) 2. 豐富的API 3. 性能好 (通過(guò)字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享) Immutab...

    孫淑建 評(píng)論0 收藏0
  • React-Redux進(jìn)階(像VUEX一樣使用Redux)

    摘要:前言是一個(gè)非常實(shí)用的狀態(tài)管理庫(kù),對(duì)于大多數(shù)使用庫(kù)的開(kāi)發(fā)者來(lái)說(shuō),都是會(huì)接觸到的。在使用享受其帶來(lái)的便利的同時(shí),我們也深受其問(wèn)題的困擾。只支持同步,讓狀態(tài)可預(yù)測(cè),方便測(cè)試。粗暴地級(jí)聯(lián)式刷新視圖使用優(yōu)化。 前言 Redux是一個(gè)非常實(shí)用的狀態(tài)管理庫(kù),對(duì)于大多數(shù)使用React庫(kù)的開(kāi)發(fā)者來(lái)說(shuō),Redux都是會(huì)接觸到的。在使用Redux享受其帶來(lái)的便利的同時(shí), 我們也深受其問(wèn)題的困擾。 redux...

    levius 評(píng)論0 收藏0
  • React+ Redux + React-route + Axios 實(shí)戰(zhàn),很適合進(jìn)階

    摘要:前言前段時(shí)間學(xué)習(xí)完了的基礎(chǔ)自己網(wǎng)上找了一些實(shí)戰(zhàn)項(xiàng)目做了幾個(gè)感覺(jué)項(xiàng)目不是很全面就想做一個(gè)完整的項(xiàng)目來(lái)提升自己的水平以前學(xué)習(xí)的時(shí)候就看過(guò)大神的項(xiàng)目所以自己打算用重寫它后端數(shù)據(jù)還是用實(shí)在沒(méi)有精力擼后端感謝大神該項(xiàng)目是餓了么目前開(kāi)發(fā)了登錄注冊(cè)購(gòu) 前言 前段時(shí)間學(xué)習(xí)完了React的基礎(chǔ),自己網(wǎng)上找了一些實(shí)戰(zhàn)項(xiàng)目,做了幾個(gè)感覺(jué)項(xiàng)目不是很全面,就想做一個(gè)完整的項(xiàng)目來(lái)提升自己的React水平.以前學(xué)習(xí)...

    phpmatt 評(píng)論0 收藏0
  • React 新 Context API 在前端狀態(tài)管理的實(shí)踐

    摘要:本文轉(zhuǎn)載至今日頭條技術(shù)博客眾所周知,的單向數(shù)據(jù)流模式導(dǎo)致?tīng)顟B(tài)只能一級(jí)一級(jí)的由父組件傳遞到子組件,在大中型應(yīng)用中較為繁瑣不好管理,通常我們需要使用來(lái)幫助我們進(jìn)行管理,然而隨著的發(fā)布,新成為了新的選擇。 本文轉(zhuǎn)載至:今日頭條技術(shù)博客showImg(https://segmentfault.com/img/bVbiNJO?w=900&h=383);眾所周知,React的單向數(shù)據(jù)流模式導(dǎo)致?tīng)顟B(tài)...

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

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

0條評(píng)論

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