美文网首页
React-redux重新梳理

React-redux重新梳理

作者: ImmortalSummer | 来源:发表于2020-05-25 19:44 被阅读0次

    Redux组成

    • state
      存放redux属性
    • action
      一个对象, 必须包含type属性
    • reducer
      根据传入的action更改state的值
    • store
      提供getState()方法获取state
      提供dispatch()方法发送action
      通过subscribe()注册监听
      通过subscribe()的返回值注销监听

    react-redux

    增加Providerconnect两个重要部分

    • Provider
      被<Provider>包围的所有组件中都可以获取store中的数据
        <Provider store={store}>
            <App></App>
        </Provider>
    
    • connect
      作用: 将组件和store关联
      Provider内部的组件如果想使用state中的数据, 必须将组件用connect进行一层封装

    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的基本流程

      1. 创建一个reducer
        const reducer = (state=defaultState, action)=>{switch(action.type) .code.. return {...state}}
      1. 创建一个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进行状态管理的组件, 可以分为发送方和接收方. (也可以同时是两者)
        接收方: 实现mapStateToProps
        发送方: 实现 mapDispatchToProps
    • mapStateToProps
      作为connect的第一个参数传入, 作用是将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的第二个参数传入, 作用是将执行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()的调用, 会执行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)
    

    相关文章

      网友评论

          本文标题:React-redux重新梳理

          本文链接:https://www.haomeiwen.com/subject/tqruahtx.html