react学习-redux部分

1、redux

安装

npm i redux

what
  • 某个组件的状态,需要让其他组件可以随时拿到(共享)
  • 一个组件需要改变另一个组件的状态(通信)
  • 总体原则:能不用就不用
工作流程图

img

核心概念
1、action
  • 1、动作的对象
  • 2、包含2个属性
    • type:标识属性, 值为字符串, 唯一, 必要属性
    • data:数据属性, 值类型任意, 可选属性
  • 3、例子:{ type: ‘ADD_STUDENT’,data:{name: ‘tom’,age:18} }
2、reducer
  • 1、用于初始化状态、加工状态。
  • 2、加工时,根据旧的state和action, 产生新的state的****纯函数********。****
3、store
  • 1、将state、action、reducer联系在一起的对象
  • 2、如何得到此对象?
      1. import {createStore} from ‘redux’
      1. import reducer from ‘./reducers’
      1. const store = createStore(reducer)
  • 3、此对象的功能?
      1. getState(): 得到state
      1. dispatch(action): 分发action, 触发reducer调用, 产生新的state
      1. subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
使用
精简版
  • (1).去除Count组件自身的状态

  • (2).src下建立:

    • -redux
      • -store.js
      • -count_reducer.js
  • (3).store.js:

    • 1).引入redux中的createStore函数,创建一个store

    • 2).createStore调用时要传入一个为其服务的reducer

    • 3).记得暴露store对象

      /**
       * 该文件专门用于暴露一个store对象,整个应用只有一个store对象
       */
      
      import { createStore } from "redux";
      //引入为count组件所服务的reducer
      import countReducer from './count_reducer';
      
      const store = createStore(countReducer);
      
      export default store;
      
  • (4).count_reducer.js:

    • 1).reducer的本质是一个函数,接收:preState,action,返回加工后的状态

    • 2).reducer有两个作用:初始化状态,加工状态

    • 3).preState为数组时不能直接使用.shifit.push,因为会出现浅拷贝

    • 4).reducer被第一次调用时,是store自动触发的:

      • 传递的preState是undefined,
      • 传递的action是:{type:’@@REDUX/INIT_a.2.b.4}
      /**
       * 该文件用于创建一个为Count组件服务的reducer,本质为函数
       * reuducer会接收两个参数,之前的状态(preState),动作对象(action)
       */
      const initState = 0;
      const countReducer = (preState = initState, action) => {
        //从action中获取,type、data
        const {type, data} = action;
        switch (type) {
          case 'increment': //如果是+
            return preState + data;
          case 'decrement':
            return preState - data;
          default:
            return preState;
        }
      };
      
      export default countReducer;
      
  • (5).在index.js中监测store中状态的改变,一旦发生改变重新渲染
    备注:redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写。

    //index.js
    import store from './redux/store';
    store.subscribe(() => {
      ReactDOM.render( < App /> , document.getElementById('root'));
    });
    
  • (6).获取store的值:store.getState()

  • (7).向store提交方法:store.dispatch({ ‘type’: ‘decrement’, data: value * 1 });

完整版

新增文件:

  • 1.count_action.js 专门用于创建action对象

    /**
     * 该文件专门为count组件生成action对象
     */
    export const createIncrementAction = (data) => {
      return {type: 'increment', data};
    };
    export const createDecrementAction = (data) => {
      return {type: 'decrement', data};
    };js
    
  • 2.constant.js 放置容易写错的type值

异步action
  • action

    • object:同步

    • function:异步

  • 安装redux-thunk

    npm i redux-thunk

  • 在store.js中添加条件

    import { createStore, applyMiddleware } from "redux";
    //引入redux-thunk,用于支持异步action
    import thunk from 'redux-thunk';
    
    const store = createStore(countReducer, applyMiddleware(thunk));
    
  • 创建异步action

    //异步任务
    export const createIncrementAsyncAction = (data, time) => {
      return (dispatch) => {
        setTimeout(() => {
          dispatch(createIncrementAction(data));
        }, time);
      };
    };
    
  • 异步action默认会调用同步action

2、react-redux

安装

​ npm i react-redux

原理图

img

项目构成
  • pages--------路由组件
  • components-------------UI组件
  • container----------------容器组件
基本使用
  • 1、index.js中去除store.subscribe,不需要进行监听,引入Provider,并包裹App

    import { Provider } from 'react-redux';
    ReactDOM.render(
      <Provider store={store}>
        < App />
      </Provider>
      , document.getElementById('root'));
    
  • 2、创建container文件夹,并创建容器组件

  • 3、在App.jsx中引入容器组件,并传入对应的store

    import store from './redux/store';
    <div>
    	<Count />
    </div>
    
  • 4、在容器组件中引入UI组件、react-redux、store的action

    // 引入Count的UI组件
    import CountUI from "../../components/Count";
    // 引入connect用于连接UI组件与redux
    import { connect } from "react-redux";
    //引入action
    import { createIncrementAction } from "../../redux/count_action";
    
  • 5、创建mapStateToProps、mapDispatchToProps两个函数

    • mapStateToProps

      • 返回的对象中的key作为传递给UI组件props的key,value作为值------状态

      • state为store传过来的,默认调用了store.getState()

      • 映射状态

        const mapStateToProps = state => ({count: state});
        /*const mapStateToProps = (state) => {
          return {
            count: state
          };
        };*/
        
    • mapDispatchToProps

      • 返回的对象中的key作为传递给UI组件props的key,value作为方法------方法

      • 默认传了store.dispatch

      • 映射操作状态的方法

      • 也可以是**对象 **

        const mapDispatchToProps = dispatch => ({
            increment(value) {
              dispatch(createIncrementAction(value));
            },
        });
        /*const mapDispatchToProps = (dispatch) =>{
          return {
            increment(value) {
              dispatch(createIncrementAction(value));
            },
          };
        };*/
        
  • 6、使用connect创建一个Count的容器组件

    export default connect(mapStateToProps, mapDispatchToProps)(CountUI);
    //简写
    export default connect(
        state => ({count: state}), 
    	{
            increment: createIncrementAction,//前提createIncrementAction需引入
        })(CountUI);
    
  • 7、在UI组件中使用值时用props中的值与方法

    this.props.increment(value * 1);
    this.props.count
    
UI组件和容器组件的整合
  • 将需要用store的UI组件和容器组件写在一个文件中

  • container的index.jsx

    // 引入connect用于连接UI组件与redux
    import { connect } from "react-redux";
    //引入action
    import { createIncrementAction, createDecrementAction, createIncrementAsyncAction } from "../../redux/count_action";
    
    import React, { Component } from 'react';
    
    class Count extends Component {....}
    
    export default connect(
      state => ({ count: state }),
      {
        increment: createIncrementAction,
        decrement: createDecrementAction,
        incrementAsync: createIncrementAsyncAction
      }
    )(Count);
    

3、组件间传递

  • 1、创建容器组件以及其action、reducer

  • 2、store.js中

    import { createStore, applyMiddleware, combineReducers } from "redux";
    //引入redux-thunk,用于支持异步action
    import thunk from 'redux-thunk';
    //引入为count组件所服务的reducer
    import countReducer from './Count/count_reducer';
    //引入为person服务的reducer
    import personReducer from "./Person/person_reducer";
    
    //汇总reducer
    //combineReducers传入的对象就是redux保存的总状态对象
    const allReducer = combineReducers({
      count: countReducer,
      personArr: personReducer,
    });
    
    const store = createStore(allReducer, applyMiddleware(thunk));
    export default store;
    
  • 容器组件中获取state

    export default connect(
      state => ({
        personArr: state.personArr,
        count: state.count
      }),//映射状态
      {
        addPerson: createAddPersonAction
      }  //映射操作状态的方法
    )(Person);
    

4、redux-devtools

安装

​ npm i redux-devtools-extension

使用
//引入redux-devtools-extension
import { composeWithDevTools } from "redux-devtools-extension";

const store = createStore(allReducer, composeWithDevTools(applyMiddleware(thunk)));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值