• React:快速上手(5)——掌握Redux(2)


    React:快速上手(5)——掌握Redux(2)

    本文部分内容参考阮一峰的Redux教程

    React-Redux原理

    React-Redux运行机制

      我觉得这张图清楚地描述React-Redux的运行机制:

      React-Redux将组件划分为两类,第一类是UI组件:

    • 只负责 UI 的呈现,不带有任何业务逻辑
    • 没有状态(即不使用this.state这个变量)
    • 所有数据都由参数(this.props)提供
    • 不使用任何 Redux 的 API

      比如,我们的实例计数器就是一个UI组件,我们只写了UI的呈现规则,并且所有数据都是由this.props提供:

    class Counter extends React.Component{
        render() {
            const{onSubmitClick,value}  = this.props;
            return(
                <div>
                    <span>{value}</span>
                    <button onClick={onSubmitClick}>提交</button>
                </div>
            )
        }
    }

      第二类组件是容器组件:

    • 负责管理数据和业务逻辑,不负责 UI 的呈现
    • 带有内部状态
    • 使用 Redux 的 API

      不过,React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成

    Connect负责从UI组件生成容器组件

      如下,一行语句,我们就将获得由UI组件得到的容器组件

    const CounterApp = connect(mapStateToProps,mapDispatchToProps)(Counter)
    

      这个函数由两个参数,mapStateToProps和mapDispatchToProps构成。它们主要定义业务逻辑,前者负责输入逻辑,即容器组件如何将state转换为props交给UI组件,来供容器组件进行UI渲染后者负责输出逻辑,用来建立 UI 组件的参数到store.dispatch方法的映射

      如下,我们定义mapStateToProps,它将state中的count字段取出映射到value属性,然后交给UI组件:

    function mapStateToProps(state) {
        return{
            value:state.count
        }
    }
    

      然后,我们定义mapDispatchToProps,他将store.dispatch方法映射到onSubmitClick属性上,这样UI组件通过props.onSubmitClick,就可以间接调用store.dispatch,实现状态更新。

    function mapDispatchToProps(dispatch) {
        return{
            onSubmitClick:()=>dispatch({type:'INCREASE'})
        }
    }

    <Provider>组件

      connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。

      React-Redux 提供Provider组件,可以让容器组件拿到state

    import { Provider } from 'react-redux'
    import { createStore } from 'redux'
    import todoApp from './reducers'
    import App from './components/App'
    
    let store = createStore(todoApp);
    
    render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    )
    

     上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。

    一个完整的计数器例子

    import React, { Component } from 'react'
    import PropTypes from 'prop-types'
    import ReactDOM from 'react-dom'
    import { createStore } from 'redux'
    import { Provider, connect } from 'react-redux'
    
    // React component
    class Counter extends Component {
      render() {
        const { value, onIncreaseClick } = this.props
        return (
          <div>
            <span>{value}</span>
            <button onClick={onIncreaseClick}>Increase</button>
          </div>
        )
      }
    }
    
    Counter.propTypes = {
      value: PropTypes.number.isRequired,
      onIncreaseClick: PropTypes.func.isRequired
    }
    
    // Action
    const increaseAction = { type: 'increase' }
    
    // Reducer
    function counter(state = { count: 0 }, action) {
      const count = state.count
      switch (action.type) {
        case 'increase':
          return { count: count + 1 }
        default:
          return state
      }
    }
    
    // Store
    const store = createStore(counter)
    
    // Map Redux state to component props
    function mapStateToProps(state) {
      return {
        value: state.count
      }
    }
    
    // Map Redux actions to component props
    function mapDispatchToProps(dispatch) {
      return {
        onIncreaseClick: () => dispatch(increaseAction)
      }
    }
    
    // Connected Component
    const App = connect(
      mapStateToProps,
      mapDispatchToProps
    )(Counter)
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    )
    

      

  • 相关阅读:
    低代码能做什么?这家服务商用钉钉宜搭打造了智慧医院管理应用
    【深度】阿里巴巴万级规模 K8s 集群全局高可用体系之美
    如何做规划?分享2种思维和4个方法
    配置审计(Config)配合开启OSS防盗链功能
    被解救的代码
    物联网海量时序数据存储有哪些挑战?
    Serverless:这真的是未来吗?(一)
    数据库学习之MySQL进阶
    网页三剑客之CSS
    网页三剑客之HTML
  • 原文地址:https://www.cnblogs.com/MrSaver/p/10314368.html
Copyright © 2020-2023  润新知