React-redux重新梳理

Redux組成

  • state
    存放redux屬性
  • action
    一個對象, 必須包含type屬性
  • reducer
    根據(jù)傳入的action更改state的值
  • store
    提供getState()方法獲取state
    提供dispatch()方法發(fā)送action
    通過subscribe()注冊監(jiān)聽
    通過subscribe()的返回值注銷監(jiān)聽

react-redux

增加Providerconnect兩個重要部分

  • Provider
    被<Provider>包圍的所有組件中都可以獲取store中的數(shù)據(jù)
    <Provider store={store}>
        <App></App>
    </Provider>
  • connect
    作用: 將組件和store關聯(lián)
    Provider內部的組件如果想使用state中的數(shù)據(jù), 必須將組件用connect進行一層封裝

connect(p1,p2,...)(component組件)第一個括號返回一個函數(shù), 這個函數(shù)的入?yún)⑹且b的組件, 返回值是被connect增強的新的組件
connect入?yún)?
funciton mapStateToProps(state,ownProps) 作用:將store中的數(shù)據(jù)作為props綁定到組件上
state:redux中的store ownProps:自己的props
function mapDispatchToProps(dispatch,ownProps) 作用:將action作為props綁定到自己的函數(shù)中
dispatch: store.dispatch() ownProps: 自己的props

一個react-redux的基本流程

    1. 創(chuàng)建一個reducer
      const reducer = (state=defaultState, action)=>{switch(action.type) .code.. return {...state}}
    1. 創(chuàng)建一個store對象
      import {createStore} from 'redux'
      const store = createStore(reducer)
    1. 將APP組件包裝進Provider, 并傳入store
      import {Provider} from 'react-redux'
      <Provider store={store}> <App/> </Provider>
    1. 使用connect加強組件
      import {connect} from 'react-redux'
      export default connect(mapStateToProps, mapDispatchToProps,...)(MyComponent)
    1. 使用redux進行狀態(tài)管理的組件, 可以分為發(fā)送方和接收方. (也可以同時是兩者)
      接收方: 實現(xiàn)mapStateToProps
      發(fā)送方: 實現(xiàn) mapDispatchToProps
  • mapStateToProps
    作為connect的第一個參數(shù)傳入, 作用是將store.state的指定屬性傳入組件的props中.

const mapStateToProps = (state)=>{
    return {
        myNumber:state.number
    }
}

export default connect(mapStateToProps)(comB)
// 通過connect的加強, comB組件的props中多了一個myNumber的屬性
// 通過this.props.myNumber的調用, 可以訪問到store.state.number這個屬性
// 當store的reducer更改了state.number的時候, 組件中引用this.props.myNumber的UI也會刷新
  • mapDispatchToProps
    作為connect的第二個參數(shù)傳入, 作用是將執(zhí)行store.dispath(action) 的方法傳入組件的props中. 例如:
const mapDispatchToProps = (dispatch)=>{
    return {
        addClicked:()=>{
            dispatch({
                type:"action_add"
            })
        }
    }
}

export default connect(null,mapDispatchToProps)(comA)
// 通過connect的加強, comA組件的props中多了一個addClicked的方法
// 通過this.props.addClicked()的調用, 會執(zhí)行store.dispatch(action)
// 執(zhí)行后會發(fā)送action, 從而是store的reducer執(zhí)行, 更新state, 進而更新UI

項目講解


[addButton] [100]


頁面效果如上, 按鈕部分定義為組件comA, 顯示數(shù)字的部分定義為組件comB. 頁面顯示在組件APP上.

工程組成:
-<store>
--index.jsx
-<reducer>
--index.jsx
-comA.jsx
-comB.jsx
-app.jsx

/*
reducer / index.jsx
*/ 

const defaultState = {
    number:100
}
exports.reducer = (state=defaultState, action)=>{
    console.log('reducer run',action.type);
    switch (action.type) {
        case 'action_add':
            return {number:state.number+1}
        default:
            break;
    }
    return state;
}
/*
store / index.jsx
*/ 
import {createStore} from 'redux'

import {reducer} from '../reducer'

export default createStore(reducer)
/*
index.jsx
*/

import React from 'react'
import ReactDOM from 'react-dom'
import {Provider} from 'react-redux'

import ComA from './ComA'
import ComB from './ComB'

import store from './store';

class App extends React.Component{
    render(){
        return <Provider store={store}>
            <ComA/>
            <ComB/>
        </Provider>
    }
}

ReactDOM.render(<App />, document.getElementById('root'));

/*
store創(chuàng)建需要傳入reducer
將<APP>組件封裝到<Provider>中, 將store作為Provider的屬性傳入.
這樣整個<APP>組件及其子組件都可以訪問到store
*/
/*
comA.jsx
*/
import React from 'react'
import {connect} from 'react-redux'

class comA extends React.Component{
    render(){
        return <div>
            <input type='button' value=' + ' onClick={this.add}></input>
        </div>
    }

    add = ()=>{
        console.log("button clicked",this.props)
        this.props.addClicked()
    }
}

// 發(fā)送方 需要實現(xiàn) connect 的第二個參數(shù) mapDispatchToProps
// 入?yún)⑹莻魅氲膕tore.dispatch
// 返回值是一個對象, 該對象的key是將要傳入的組件中的props的方法, value傳一個箭頭函數(shù), 函數(shù)中調用dispatch()
// dispatch()的入?yún)⑹且粋€action對象, action對象一定要有type屬性

// 該方法會將addClicked方法注入到組件的props中去, 組件中執(zhí)行this.props.addClicked(), 相當于執(zhí)行了store.dispatch(action)
// 每當store.dispatch(action)執(zhí)行時, store 而這個action的type就是action_add. 
const mapDispatchToProps = (dispatch)=>{
    return {
        addClicked:()=>{
            dispatch({
                type:"action_add"
            })
        }
    }
}

export default connect(null,mapDispatchToProps)(comA)

/*
comB.jsx
*/

import React from 'react'
import {connect} from 'react-redux'

class comB extends React.Component{
    render(){
        return <div>
            <p>{this.props.myNumber}</p>
        </div>
    }
}

// 接收方 需要實現(xiàn)connect的第一個參數(shù) mapStateToProps
// 入?yún)⑹莝tore.state 返回值是一個對象, key是注入到組件的props中的屬性名, value可以從state中取
// 注入后可以再組件中的props中方為到state的屬性了
const mapStateToProps = (state)=>{
    return {
        myNumber:state.number
    }
}

export default connect(mapStateToProps)(comB)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容