继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

React-Redux API 学习小记

王益达
关注TA
已关注
手记 38
粉丝 104
获赞 632
React-Redux API 简介 功能摘要
  1. React-Redux 是为了方便在 React 项目中使用 Redux 所封装的库
  2. React-Redux 把组件分为两类:UI 组件(Component)和容器组件(Container)
  3. React-Redux 提供 Provider 组件,使它的子组件(容器组件)都能拿到 state
UI 组件(纯组件)

UI 组件特征:

  1. 只负责 UI 的呈现,不带有任何业务逻辑
  2. 没有状态(this.state)
  3. 所有数据都由组件属性(this.props)提供
  4. 不使用任何 Redux 的 API

UI 组件示例:

const Title = value => <h1>{value}</h1>;
容器组件(逻辑组件)

容器组件特征:

  1. 负责管理数据和业务逻辑,不负责 UI 的呈现
  2. 带有内部状态
  3. 通过 Redux 的 API 生成
混合组件(UI + 逻辑)

如果一个组件既有 UI 呈现又有业务逻辑,则将它封装为如下结构:

  1. 外面是一个容器组件,里面包裹一个UI 组件
  2. 容器组件负责与外部的通信,将数据传给 UI 组件
  3. UI 组件接受数据,并渲染出视图
React-Redux API

由 UI 组件生成容器组件,需要三个要素:

  1. 连接通信 - 连接 UI 组件和容器组件,为输入输出 state 做准备
  2. 逻辑输入 - 将容器组件的 state 映射为 UI 组件的 props
  3. 逻辑输出 - 用户动作触发 UI 组件绑定事件,dispatch 更新容器组件 state

容器组件的三要素对应 React-Redux 的 API:

  1. 连接通信 - connect
  2. 逻辑输入 - mapStateToProps
  3. 逻辑输出 - mapDispatchToProps

其中,mapStateToProps 和 mapDispatchToProps 作为 connect 的参数传入

1. connect() 示例:

import {connect} from 'react-redux';

const Container = connect(
    mapStateToProps,
    mapDispatchToProps
)(Component);

2. mapStateToProps() 示例:

const mapStateToProps = (state, ownProps) => {
    return props;
};

mapStateToProps 会订阅 Store,每当 state 更新,就会自动执行,重新计算 UI 组件的 props,从而触发 UI 组件的重新渲染

3. mapDispatchToProps 示例:

3.1 mapDispatchToProps 函数:

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        handleClick: () => {
            dispatch(action);
        }
    };
};

3.2 mapDispatchToProps 对象:

const mapDispatchToProps = {
    handleClick: actionCreator;
};

mapDispatchToProps 用来建立 UI 组件的 props 到 Store.dispatch 方法的映射

至此,容器组件与内部的 UI 组件的通信已经解决。容器组件还需要与外部通信,拿到 state 对象。
React-Redux 提供 Provider 组件,可以让容器组件拿到 state。

4. Provider 示例:

import {Provider} from 'react-redux';
import {createStore} from 'redux';
import todoApp from './reducers';
import App from './components/App';

const store = createStore(todoApp);

render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);

Provider 在【根组件】App 外面包了一层。这样,所有子组件就可以拿到 state 了

React-Redux 综合实例:

实现步骤:

  1. 定义 UI 组件。规划组件属性 this.props,组件属性包括【展示属性】和【绑定事件】
  2. 定义组件通信。包括【展示数据】到 state 的映射、【绑定事件】到 dispatch 的映射
  3. 将 UI 组件包装成容器组件
  4. 定义容器组件的 Reducer
  5. 生成 Store 对象,并使用 Provider 在根组件外面包一层

流程概括如下:

 Component 
        - [mapDispatchToProps/mapDispatchToProps] -
     => Container
         - [connect] -
         - [Reducer] -
     => Store + Provider

计数器(Counter)示例:

  1. 导入所需组件(确保依赖已安装)

    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';
  2. 定义 UI 组件

    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
    };
  3. 定义组件通信

    // Action Creator
    const increaseAction = {
        type: 'increase'
    };
    
    const mapStateToProps = state => {
        return {value: state.count}
    };
    
    const mapDispatchToProps = dispatch => {
        return {
            onIncreaseClick: () => dispatch(increaseAction);
        }
    };
  4. 包装容器组件

    const App = connect(
        mapStateToProps,
        mapDispatchToProps
    )(Counter);
  5. 定义 Reducer

    function counter(state = {count: 0}, action) {
        const count = state.count;
        switch (action.type) {
            case 'increase':
                return {
                    count: count + 1
                };
            default:
                return state;
        }
    }
  6. 生成 Store 对象

    const store = createStore(counter)
    ReactDOM.render(
        <Provider store={store}>
            <App/>
        </Provider>,
        document.getElementById('root')
    );

    Tips: 本文总结自阮一峰老师的文章 React-Redux 的用法,如果对您有帮助,可以给阮一峰老师留言感谢 !

打开App,阅读手记
13人推荐
发表评论
随时随地看视频慕课网APP