React-redux重新梳理

2020-05-25  本文已影响0人  ImmortalSummer

Redux组成

react-redux

增加Providerconnect两个重要部分

    <Provider store={store}>
        <App></App>
    </Provider>

connect(p1,p2,...)(component组件)第一个括号返回一个函数, 这个函数的入参是要包装的组件, 返回值是被connect增强的新的组件
connect入参:
funciton mapStateToProps(state,ownProps) 作用:将store中的数据作为props绑定到组件上
state:redux中的store ownProps:自己的props
function mapDispatchToProps(dispatch,ownProps) 作用:将action作为props绑定到自己的函数中
dispatch: store.dispatch() ownProps: 自己的props

一个react-redux的基本流程

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也会刷新
const mapDispatchToProps = (dispatch)=>{
    return {
        addClicked:()=>{
            dispatch({
                type:"action_add"
            })
        }
    }
}

export default connect(null,mapDispatchToProps)(comA)
// 通过connect的加强, comA组件的props中多了一个addClicked的方法
// 通过this.props.addClicked()的调用, 会执行store.dispatch(action)
// 执行后会发送action, 从而是store的reducer执行, 更新state, 进而更新UI

项目讲解


[addButton] [100]


页面效果如上, 按钮部分定义为组件comA, 显示数字的部分定义为组件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创建需要传入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()
    }
}

// 发送方 需要实现 connect 的第二个参数 mapDispatchToProps
// 入参是传入的store.dispatch
// 返回值是一个对象, 该对象的key是将要传入的组件中的props的方法, value传一个箭头函数, 函数中调用dispatch()
// dispatch()的入参是一个action对象, action对象一定要有type属性

// 该方法会将addClicked方法注入到组件的props中去, 组件中执行this.props.addClicked(), 相当于执行了store.dispatch(action)
// 每当store.dispatch(action)执行时, 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>
    }
}

// 接收方 需要实现connect的第一个参数 mapStateToProps
// 入参是store.state 返回值是一个对象, key是注入到组件的props中的属性名, value可以从state中取
// 注入后可以再组件中的props中方为到state的属性了
const mapStateToProps = (state)=>{
    return {
        myNumber:state.number
    }
}

export default connect(mapStateToProps)(comB)
上一篇 下一篇

猜你喜欢

热点阅读