react-redux基本使用

还在学习中…

学习视频

动机

引用地址

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。

管理不断变化的 state 非常困难。如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依次地,可能会引起另一个 view 的变化。

React-Redux 之store, action, reducer

在这里插入图片描述

react-redux组件处理

react-redux会将所有的组件分为两大类:UI组件和容器组件。

UI组件特征:

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

容器组件特征:

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

总结一句话:UI组件只是负责UI的呈现,容器组件是负责管理数据和业务逻辑的。

connect高阶函数

react-redux规定所有的UI就是用户提供的,也就是render函数返回的代码,容器组件是由react-redux自动生成的,用户只需要负责页面展示,状态管理交给react-redux。

UI组件:

render() {
   return (
     <div>
       <button type="submit" onClick={this.handleClick.bind(this)}>
         添加
       </button>
     </div>
   );
 }

如何让一个普通的UI组件分为UI组件和容器组件?

使用react-redux的connect方法,ComA是用户自定义的UI组件,通过connect函数生成容器组件(container),当然这样的组件也只是多包裹了一层而已,还需要绑定数据和定义业务逻辑。

import { connect } from "react-redux";
const container = connect(mapStateToProps, mapStateDispatchToProps, mergeProps?)(ComA);
export default container;

mapStateToProps()

mapStateToProps()它是一个函数,它的作用就是建立一个state对象到props对象的映射关系,这个函数的返回值是一个{key: value}对象。 mapStateToProps()会将redux的store(state)中的数据会作为props绑定到组件上。

const mapStateToProps = (state,ownProps) => {
  // ownProps表示当前组件的props
  // console.log(state);
  return {
    num: state.num, // 当前组件的props就多了一个num,值为store里面的num的值
  };
};

在这里插入图片描述

个人理解组件代码:首先这是一个普通的UI组件,但是经过connect处理过后,就可以与store联系起来,然后通过connect的第一个参数mapStateToProps将store的内容与当前组件的props联系起来。从而达到了当store里面的数据更新了,当前组件也会随着改变。

mapStateDispatchToProps()

mapDispatchToProps是connect函数的第二个参数,用来建立UI组件的参数到store.dispatch方法的映射,它定义了用户的操作应该当做action传递给store。

const mapStateDispatchToProps = (dispatch, ownProps) => {
// ownProps表示当前组件的props
  return {
    sendAddAction() {
      dispatch({ // dispatch分发动作, reducer进行处理
        type: "add_action",
        value: 2,
      });
    },
  };
};

在这里插入图片描述

个人理解组件代码:mapStateDispatchToProps中定义一个方法,等着用户去触发,一旦触发了就会执行dispatch从而将type和value发送给reducerreducer收到通知过后,根据type类型,从而执行相应的逻辑操作。

mergeProps()

获取 mapStateToProps, mapStateDispatchToProps以及当前组件props属性

const mergeProps = (...arg) => {
  console.log(arg); // stateProps, dispatchProps, ownProps
};

Provider组件

connect()函数生成了容器组件过后,需要让容器组件拿到state对象,才能生成UI组件的参数。

Provider只要是被他包裹的容器组件都可以拿到state对象。

// store/index.js文件
import { createStore } from "redux";
import reducers from "../reducer";
export default createStore(reducers);

// App.js文件
import store from "./store";
function App() {
  return (
    <Provider store={store}>
      <ComA></ComA>
      <ComB></ComB>
    </Provider>
  );
}

完整实例,计数器

  1. 初始化操作,编写store,reducer

    reducer不允许直接修改state, 修改复杂类型可使用JSON.parse(JSON.stringify())进行深拷贝, 在新对象身上修改, 最后返回.

在这里插入图片描述

  1. 编写组件A

    import React, { Component } from "react";
    import { connect } from "react-redux";
    
    class ComA extends Component {
      constructor(props) {
        super(props);
      }
      handleClick() {
        this.props.sendAddAction();
      }
      render() {
        return (
          <div>
            <button type="submit" onClick={this.handleClick.bind(this)}>
              添加
            </button>
          </div>
        );
      }
    }
    // 第二个参数, 是发送数据, 也就是页面中触发一个动作, 
    // 进而触发函数, 函数就会向reducer发送一个action, 表示要操作state了;
    const mapStateDispatchToProps = (dispatch) => {
      return {
        sendAddAction() {
          dispatch({
            type: "add_action",
            value: 2,
          });
        },
      };
    };
    
    const container = connect(null, mapStateDispatchToProps)(ComA);
    export default container;
    
  2. 编写组件B

    import React, { Component } from "react";
    import { connect } from "react-redux";
    
    class ComB extends Component {
      render() {
        console.log(this.props);
        return (
          <div>
            <h1>{this.props.num}</h1>
          </div>
        );
      }
    }
    
    const mapStateToProps = (state) => {
      // console.log(state);
      return {
        num: state.num,
      };
    };
    export default connect(mapStateToProps)(ComB);
    
  3. App.js

    import "./App.css";
    import { Provider } from "react-redux";
    import ComA from "./page/comA";
    import ComB from "./page/comB";
    // ***************************************
    import store from "./store";
    // ***************************************
    function App() {
      return (
        <Provider store={store}>
          <ComA></ComA>
          <ComB></ComB>
        </Provider>
      );
    }
    
    export default App;
    
  4. 页面截图
    在这里插入图片描述

整个操作流程:

  1. 开始页面就显示store里面的num,也就是第三个步骤的{this.props.num},因为connect处理过后,就可以与store联系起来,进而可以通过props获取到store里面的num。
  2. 用户执行了点击操作(步骤二),发送了一个type为’add_action’的操作,接着传递给reducer,reducer根据type来执行操作也就是步骤一。
  3. 所有的前提就是组件要有store(步骤四),因此Provider这个步骤尤为重要。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值