• redux 的基础用法


    目录结构:

    (根目录)
      src
        |-assets  // 公共资源
        |-components  // 公共组件
        |-pages  // 页面
        |-router  // 路由
        |-store  // 公共状态管理 redux
          |-action-types.js  // 行为标识(必须是唯一的)
          |-action.js  // 常说的,发起一个action。通过函数传入新的数据,替换之前的store。
          |-reducer.js  // 相当于一个管理员,基于不同的行为标识,修改store中不同的状态。
          |-store.js  // store相当于一个仓库,存储各种数据。这个文件的作用是,整合文件。
      App.js  // 
      index.js  // 入口文件
    
    1. index.js 文件
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import { BrowserRouter as Router } from "react-router-dom";
    
    // 还没有用到 redux 的时候,引用 Provider 等,会报错。
    // Provider 标签需要放在最外层
    import {Provider} from 'react-redux';
    import store from "./store/store";
    if (module.hot) {
        module.hot.accept();
    }
    ReactDOM.render(
      <Provider store={store}>
        <Router>
          <App />
        </Router>
      </Provider>
      ,
      document.getElementById('root')
    );
    
    2. action-types.js 文件
    export const HTMLFONTSIZE = 'HTMLFONTSIZE';
    export const DATAONE = 'DATAONE';
    export const DATATWO = 'DATATWO';
    // ...
    
    3. action.js 文件
    /*
    没有使用 react-thunk , 只能返回一个对象
    */
    // import * as Types from './action-types';
    // let actions = {
    //   changeFontSize(obj) {
    //     return { type: Types.HTMLFONTSIZE, obj }
    //   }
    // };
    // export default actions;
    
    /*
    引入thunk插件后,我们可以在actionCreators内部编写逻辑,处理请求结果。而不只是单纯的返回一个action对象。
    */
    import * as Types from './action-types';
    function changeFontSize(param) {
      return (dispatch) => {
        setTimeout(() => { // 模拟异步(这里可以是一次数据请求)
          dispatch(changeFontSizeAction(param));
        }, 3000)
      }
    }
    
    function changeFontSizeAction(obj) {
      return { type: Types.HTMLFONTSIZE, obj }
    }
    
    export {
      changeFontSize
    };
    
    4. reducer.js 文件
    import * as Types from './action-types';
    
    const obj = {
      htmlFontSize: 0
    }
    
    function reducer(state = obj, action) {
      switch (action.type) {
        case Types.HTMLFONTSIZE:
          return {...state, ...action.obj};
        default:
          return JSON.parse(JSON.stringify(state));
      }
    }
    export default reducer;
    
    5. store.js 文件
    /*
      import { createStore } from 'redux';
      import reducer from './reducer';
      const store = createStore(reducer);
      // window._store = store; //在window上挂一个叫_store的属性,可以看到store里面的内容
      export default store;
    */
    
    // 使用 thunk 后,可以这样写:
    import { createStore, applyMiddleware } from "redux";
    import reducer from './reducer';
    import thunk from "redux-thunk";
    const store = createStore(
      reducer,
      applyMiddleware(thunk)
    )
    export default store;
    

    使用 thunk 中间件。以及:combineReducers、applyMiddleWare、compose、applyMiddleware()
    使用包含自定义功能的 middleware 来扩展 Redux 是一种推荐的方式。 例如,redux-thunk 支持 dispatch function,以此让 action creator 控制反转。 被 dispatch 的 function 会接收 dispatch 作为参数,并且可以异步调用它。 这类的 function 就称为 thunk。另一个 middleware 的示例是 redux-promise。 它支持 dispatch 一个异步的 Promise action,并且在 Promise resolve 后可以 dispatch 一个普通的 action。 compose 可以将中间件组合拼装,使组件更加强大。

    使用中间件的 store
    import { createStore, combineReducers, applyMiddleware, compose } from "redux";
    import thunk from "redux-thunk";
    const store = createStore(
      //如果有多个 reducer ,将多个 reducer 整合在一起(项目只有一个reducer时,不建议使用并且会出现错误提示)
      combineReducers(reducer, reducer1, reducer2),
      applyMiddleware(thunk) //可以在 action 中做异步处理 dispatch
      //如果有多个中间件就可以这样写:compose(applyMiddleware(thunk), xxxx, xxxxx)
    )
    

    这样,就可以使用 redux 了。
    在此之前,我们习惯:哪里需要用到接口,就在哪个页面(文件)中调取。
    现在,通过中间件 thunk 可以让程序员在 action 中调用接口。
    下面具体说一下,中间件 thunk 的使用方式。

    使用 applyMiddleware(thunk) 之后,action 中可以这样写:
    import * as Types from './action-types';
      function getList(param) {
        return (dispatch) => {
          setTimeout(() => {     // 模拟异步(这里可以是一次数据请求)
            dispatch listData(param)
          }, 5000)
        }
      }
      function listData(obj) {
        return { type: Types.LISTDATA, obj }
      }
    export {
      getList
    };
    
    项目组件中使用的例子:
    import { getList } from "../../store/store";
    import React, { Component } from "react";
    import "./BaseEchart.less";
    import connect from "react-redux/es/connect/connect";
    class BaseEchart extends Component {
      constructor(props) {
        super(props);
      };
      componentDidMount() {
        const param = {
          startTime: "2019-10-20 12:00:00",
          endTime: "2019-10-21 12:00:00"
        }
        this.props.getList(param)
      }
      // UNSAFE_componentWillMount,
      componentWillReceiveProps(nextProps) {
        if (nextProps.listData !== this.props.listData) {
          console.log(nextProps.actions.listData)
        }
      }
      //componentWillUnmount() {}
      render() {
        return (
          <div className="BaseEchart">
          </div>
        )
      }
    }
    export default connect(state => state, {getList})(BaseEchart);
    
  • 相关阅读:
    如何通过关键词匹配统计其出现的频率
    好玩的SQL
    如何用Dummy实例执行数据库的还原和恢复
    如何查找特定目录下最大的文件及文件夹
    《Administrator's Guide》之Managing Memory
    Oracle如何实现从特定组合中随机读取值
    如何用分析函数找出EMP表中每个部门工资最高的员工
    Oracle之DBMS_RANDOM包详解
    RAC碎碎念
    如何利用Direct NFS克隆数据库
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/14151388.html
Copyright © 2020-2023  润新知