React项目集成Immutable.js

栏目: JavaScript · 发布时间: 5年前

内容简介:本文章项目的依赖包及其版本如下:下面是我的项目结构,每个人或者每个公司都有自己的目录架构,这里我的只供大家参考,另外搭建项目过程和介绍如何使用immutable.js不是本文章的重点,如何使用immutable.js以及本文章相关代码后面我会给出,如果有疑问欢迎大家在下面留言此项目除了依赖包要配置之外,只有redux下的reducer相关文件会设置成immutable.js普通的react组件我没有设置成immutable.js

1、前言

本文章项目的依赖包及其版本如下:

Package Name Version
antd ^3.16.6
connected-react-router ^6.4.0
customize-cra ^0.2.12
immutable ^4.0.0-rc.12
react ^16.8.6
react-app-rewired ^2.1.1
react-redux ^7.0.3
react-router-config ^5.0.0
react-router-dom ^5.0.0
react-scripts 3.0.1
redux ^4.0.1
redux-logger ^3.0.6
redux-persist ^5.10.0
redux-persist-expire ^1.0.2
redux-persist-transform-immutable ^5.0.0
redux-saga ^1.0.2

2、准备工作,搭建项目

下面是我的项目结构,每个人或者每个公司都有自己的目录架构,这里我的只供大家参考,另外搭建项目过程和介绍如何使用immutable.js不是本文章的重点,如何使用immutable.js以及本文章相关代码后面我会给出,如果有疑问欢迎大家在下面留言

|-- App.js
|-- index.js
|-- serviceWorker.js
|-- assets
|   |-- audio
|   |-- css
|   |   |-- App.scss
|   |   |-- base.scss
|   |   |-- index.css
|   |   |-- override-antd.scss
|   |-- image
|   |   |-- Welcome.png
|   |   |-- awbeci.png
|   |   |-- bgLogo.png
|   |   |-- hiy_logo.png
|   |   |-- indexPop1.png
|   |   |-- indexPop2.png
|   |   |-- logo.png
|   |   |-- logoX.png
|   |   |-- right.png
|   |-- video
|-- components
|   |-- HOC
|   |   |-- loading.js
|   |-- common
|   |-- layout
|       |-- AppRoute.js
|       |-- LayoutPage.js
|       |-- Loading.js
|       |-- MasterPage.js
|       |-- RouterView.js
|       |-- SideMenu.js
|       |-- layoutPage.scss
|       |-- masterPage.scss
|-- config
|   |-- base.conf.js
|-- context
|   |-- themeContext.js
|-- pages
|   |-- DepartmentManage.js
|   |-- Index.js
|   |-- NoFound.js
|   |-- NoPermission.js
|   |-- UserManage.js
|   |-- login
|       |-- Login.js
|       |-- login.scss
|-- redux
|   |-- actions
|   |   |-- authAction.js
|   |   |-- layoutPageAction.js
|   |-- middleware
|   |   |-- authTokenMiddleware.js
|   |-- reducers
|   |   |-- authReducer.js
|   |   |-- index.js
|   |   |-- layoutPageReducer.js
|   |-- sagas
|   |   |-- authSaga.js
|   |   |-- index.js
|   |-- store
|   |   |-- index.js
|   |-- thunks
|-- router
|   |-- index.js
|-- service
|   |-- apis
|   |   |-- 1.0
|   |       |-- index.js
|   |       |-- urls.js
|   |-- mocks
|   |   |-- 1.0
|   |       |-- index.js
|   |       |-- testMock.js
|   |-- request
|       |-- ApiRequest.js
|       |-- MockRequest.js
|-- test
|   |-- App.test.js
|-- utils

3、集成immutable.js

此项目除了依赖包要配置之外,只有redux下的reducer相关文件会设置成immutable.js普通的react组件我没有设置成immutable.js

App.js

import { ConnectedRouter } from "connected-react-router";
//换成
import { ConnectedRouter } from "connected-react-router/immutable";

store->index.js

import { routerMiddleware } from "connected-react-router";
//换成
import { routerMiddleware } from "connected-react-router/immutable";
//添加
import immutableTransform from "redux-persist-transform-immutable";

const persistConfig = {
  transforms: [encryptor],
  //换成
  transforms: [
    immutableTransform()
    // 注意:必须要注释encryptor否则会报错
    // encryptor
  ],
  ...
}

redux->reducers->index.js

import { connectRouter } from "connected-react-router";
//换成
import { connectRouter } from "connected-react-router/immutable";

redux->reducers->authReducer.js

//添加
import { Map, fromJS, merge } from "immutable";

const initState = {
  user: null,
  token: ""
};

[authTypes.AUTH_SUCCESS]: (state, action) => {
      return Object.assign({}, state, { user: action.data.user, token: action.data.token });
    },
    [authTypes.SIGN_OUT]: (state, action) => {
      return Object.assign({}, state, {
        user: null,
        token: ""
      });
    }
//换成
const initState = fromJS({
  user: null,
  token: ""
});

    [authTypes.AUTH_SUCCESS]: (state, action) => {
      return state.merge({
        user: action.data.user,
        token: action.data.token
      });
    },
    [authTypes.SIGN_OUT]: (state, action) => {
      return state.merge({
        user: null,
        token: ""
      });
    }

redux->reducers->layoutPageReducer.js

//添加
import { Map, fromJS, merge, List } from "immutable";

const initState = {
  index: "126",
  subIndex: "",
  collapsed: false,
  menus: [],
  loading: false
};
[layoutPageTypes.SAVE_MENU_INDEX]: (state, action) => {
      const { keyPath } = action.payload;
      let index = keyPath[0];
      let subIndex = null;
      if (keyPath.length === 2) {
        subIndex = keyPath[1];
      }
      return Object.assign({}, state, {
        index: index,
        subIndex: subIndex
      });
    },
    [layoutPageTypes.SAVE_MENU_COLLAPSED]: (state, action) => {
      const { collapsed } = action.payload;
      return Object.assign({}, state, {
        collapsed: collapsed
      });
    },
    [layoutPageTypes.GET_MENUS]: (state, action) => {
      const { menus } = action;
      return Object.assign({}, state, {
        menus: menus
      });
    }
//换成
const initState = fromJS({
  index: "126",
  subIndex: "",
  collapsed: false,
  menus: List()
});

[layoutPageTypes.SAVE_MENU_INDEX]: (state, action) => {
      const { keyPath } = action.payload;
      let index = keyPath[0];
      let subIndex = null;
      if (keyPath.length === 2) {
        subIndex = keyPath[1];
      }
      return state.merge({
        index: index,
        subIndex: subIndex
      });
    },
    [layoutPageTypes.SAVE_MENU_COLLAPSED]: (state, action) => {
      const { collapsed } = action.payload;
      return state.merge({
        collapsed: collapsed
      });
    },
    [layoutPageTypes.GET_MENUS]: (state, action) => {
      const { menus } = action;
      return state.merge({
        menus: menus
      });
    }

middleware->authTokenMiddleware.js

//添加
import { fromJS } from "immutable";

if (action.type === REHYDRATE) {
    if (action.payload && action.payload.authReducer && action.payload.authReducer.token) {
      ApiRequest.setToken(action.payload.authReducer.token);
    }
  }
//换成
if (action.type === REHYDRATE) {
    if (typeof action.payload !== "undefined") {
      let authReducer = action.payload.authReducer;
      if (authReducer) {
        const token = authReducer.get("token");
        ApiRequest.setToken(token ? token : null);
      }
    }
  }

components->layout->LayoutPage.js

<span style={{ marginLeft: 8 }}>{authReducer.user ? authReducer.user.name : "用户"}</span>

<Switch>{authReducer.token ? renderRoutes(routes) : <Redirect to="/login" />}</Switch>
//换成
<span style={{ marginLeft: 8 }}>{authReducer.get("user") ? authReducer.getIn(["user", "name"]) : "用户"}</span>

<Switch>{authReducer.get("token") ? renderRoutes(routes) : <Redirect to="/login" />}</Switch>

components->layout->SideMenu.js

let menus = layoutPageReducer.menus;

<Menu
          theme="light"
          defaultSelectedKeys={[layoutPageReducer.index]}
          selectedKeys={[layoutPageReducer.index]}
          defaultOpenKeys={[layoutPageReducer.subIndex]}
          mode="inline"
          className="sider-menu-container"
          inlineCollapsed={layoutPageReducer.collapsed}
          onClick={this.clickSidebarMenu}
        >
          {newMenus}
        </Menu>
//换成
let menus = layoutPageReducer.get("menus");

        <Menu
          theme="light"
          defaultSelectedKeys={[layoutPageReducer.get("index")]}
          selectedKeys={[layoutPageReducer.get("index")]}
          defaultOpenKeys={[layoutPageReducer.get("subIndex")]}
          mode="inline"
          className="sider-menu-container"
          inlineCollapsed={layoutPageReducer.get("collapsed")}
          onClick={this.clickSidebarMenu}
        >
          {newMenus}
        </Menu>

components->layout->AppRoute.js

Authentication() {
    return this.props.store.authReducer.token ? <Redirect to="/" /> : <Login />;
  }
//换成
    return this.props.store.authReducer.get("token") ? <Redirect to="/" /> : <Login />;

4、启动项目看是否集成成功

命令行运行: yarn start

React项目集成Immutable.js

清除下缓存尤其是localstorage,如果看到上面的登录页面那么恭喜你配置成功!

5、redux-logger 打印immutable.js日志

下面我们来看看redux-logger打印的日志跟我们不使用immutable.js有什么区别?

React项目集成Immutable.js

如上图所示,打印的日志数据就是immutable.js的相关数据,但是我们会发现阅读性不是太好,这里我们安装一个格式化immutable.js的日志数据的Chrome插件,安装一下即可,之前我有写过一篇文章教你怎么使用这个插件,点击跳转阅读,安装好之后,我们再来查看数据,如下所示:

React项目集成Immutable.js

是不是增加了日志的可阅读性,到此我们集成Immutable.js就至此结束,欢迎大家在下面留言交流!

5、总结

1)上面是教你如何把现有项目集成immutable.js,如果你是新项目,上面有些配置其实是不用管的;

2)上面的集成原则:把原生的写法改成immutable.js的写法即可!;

3)这里我用到了redux-persist,如果你没有用到这个包,那么你就可以不用安装redux-persist-transform-immutable,换成redux-immutable包即可,具体如何操作,官方文档上面有讲,这里就不多说了。

4) 演示地址本文章代码 ,另外本文章代码对应github上面的immutable.js分支,而演示地址对应的是master分支!

6、引用

1. Immutable.js了解一下?

2. React引用数据类型与immutable.js的使用实例

3. react 使用的小建议

4. Immutable.js 以及在 react+redux 项目中的实践

5. React Native Redux、redux-persist、immutable.js 结合实践

6. Error when using redux-persist with redux-immutable

7. 大话immutable.js

8. Immutable.js 以及在 react+redux 项目中的实践

9. Immutable.js与React,Redux及reselect的实践

10. 如何用React+Redux+ImmutableJS进行SPA开发

11. immutable.js 在React、Redux中的实践以及常用API简介

12. 笔记, immutable-js 基础操作

13. Immutable.js 到底值不值得用?

14. Immutable 详解及 React 中实践

15. Immutable.js与React,Redux及reselect的实践


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First HTML与CSS(第2版)

Head First HTML与CSS(第2版)

Elisabeth Robson、Eric Freeman / 徐阳、丁小峰 / 中国电力出版社 / 2013-9 / 98.00元

是不是已经厌倦了那些深奥的HTML书?你可能在抱怨,只有成为专家之后才能读懂那些书。那么,找一本新修订的《Head First HTML与CSS(第2版)》吧,来真正学习HTML。你可能希望学会HTML和CSS来创建你想要的Web页面,从而能与朋友、家人、粉丝和狂热的顾客更有效地交流。你还希望使用最新的HTML5标准,能够保证随时间维护和扩展你的Web页面,使它们在所有浏览器和移动设备中都能正常工......一起来看看 《Head First HTML与CSS(第2版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码