iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Reactimmer与ReduxToolkit使用教程详解
  • 813
分享到

Reactimmer与ReduxToolkit使用教程详解

ReactimmerReactReduxToolkit 2022-11-13 18:11:41 813人浏览 泡泡鱼
摘要

目录1. immer1.1 setState结合immer使用1.2 useState结合immer使用1.3 immer和redux集合2. Redux Toolkit1. imm

1. immer

概述:

它和immutable相似的,实现了操作对象的数据共享,可以优化性能。它实现的原理使用es6的Proxy完成的。小巧,没有像immutable哪样有新数据类型,而是使用js类型。

安装:

yarn add immer@9

1.1 setState结合immer使用

简单使用:

import React from 'react'
// 把源数据使用Proxy进行代理处理,后面就可以精准的去找到变化的数据
import { produce } from 'immer'
const state = {
  count: 1
}
// 进行代理后,并修改
// draft就是代理对象,它就是state代理对象
const newState = produce(state, draft => {
  draft.count++
})
console.log(newState.count)// 2
const App = () => {
  return <div></div>
}
export default App

使用immer进行proxy代理,源数据中只有变化的了的数据才更新,没有变化则共享,这样做可以提高性能:

import React from 'react'
// 把源数据使用Proxy进行代理处理,后面就可以精准的去找到变化的数据
import { produce } from 'immer'
const baseState = {
  arr: [1, 2, 3],
  obj: { id: 1, name: '张三' }
}
// 使用immer进行proxy代理,源数据中只有变化的了的数据才更新,没有变化则共享,提高性能
const newState = produce(baseState, draft => {
  draft.arr.push(4)
})
// 当前只修改数组,对象没有修改,共享
console.log('arr', newState.arr === baseState.arr) // false
console.log('obj', newState.obj === baseState.obj) // true
const App = () => {
  return <div></div>
}
export default App

使用 immer 优化 setState 使用:

import React, { Component } from 'react'
import { produce } from 'immer'
// 优化setState更新数据
class App extends Component {
  state = {
    count: 100,
    carts: [
      { id: 1, name: 'aa', num: 1 },
      { id: 2, name: 'bb', num: 2 }
    ]
  }
  addCount = () => {
    // 原来的写法
    // this.setState(state => ({ count: state.count + 1 }))
    // 使用immer来优化setState操作
    this.setState(
      produce(draft => {
        // 不用返回,返加不允许,draft它是一个代理对象,修改后,它能监听到数据的变化,更新视图
        draft.count++
      })
    )
  }
  render() {
    return (
      <div>
        <h3>{this.state.count}</h3>
        <button onClick={this.addCount}>++++++</button>
        <hr />
        {this.state.carts.map((item, index) => (
          <li key={item.id}>
            <span>{item.name}</span>
            <span>---</span>
            <span>
              {item.num} --
              <button
                onClick={() => {
                  this.setState(
                    produce(draft => {
                      // draft它就是当前的this.state
                      draft.carts[index].num++
                    })
                  )
                }}
              >
                ++++
              </button>
            </span>
          </li>
        ))}
      </div>
    )
  }
}
export default App

1.2 useState结合immer使用

import React, { useState } from 'react'
import { produce } from 'immer'
const App = () => {
  // 普通的数字,不是proxy代理,proxy代理的是对象
  // 如果它是一个普通值,没有必要使用immer来完成优化操作
  let [count, setCount] = useState(100)
  // 对象类型才是使用immer工作的场景
  let [carts, setCarts] = useState([
    { id: 1, name: 'aa', num: 1 },
    { id: 2, name: 'bb', num: 2 }
  ])
  return (
    <div>
      <h3>{count}</h3>
      <button
        onClick={() => {
          // 之前的写法
          // setCount(v => v + 1)
          setCount(produce(draft => draft + 1))
        }}
      >
        +++count+++
      </button>
      <hr />
      <button
        onClick={() => {
          setCarts(
            produce(draft => {
              draft.push({ id: Date.now(), num: 1, name: 'aaaa--' + Date.now() })
            })
          )
        }}
      >
        添加商品
      </button>
      {carts.map((item, index) => (
        <li key={item.id}>
          <span>{item.name}</span>
          <span>---</span>
          <span>
            {item.num} --
            <button
              onClick={() => {
                setCarts(
                  produce(draft => {
                    // 不能返回,写上去感觉就像在Vue的感觉
                    draft[index].num++
                  })
                )
              }}
            >
              ++++
            </button>
          </span>
          <span
            onClick={() => {
              setCarts(
                produce(draft => {
                  draft.splice(index, 1)
                })
              )
            }}
          >
            删除
          </span>
        </li>
      ))}
    </div>
  )
}
export default App

1.3 immer和redux集合

redux/index.js:

import { createStore } from 'redux'
import { produce } from 'immer'
const initState = {
  count: 100
}
// 以前的写法

const reducer = produce((draft, { type,  payload }) => {
  // 写法就和vuex中的mutation中的写法一样的,简化了
  // 操作数据无需深复制,提升性能
  if ('add' === type) draft.count += payload
}, initState)
export default createStore(reducer)

前端页面:

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
const App = () => {
  const dispatch = useDispatch()
  const count = useSelector(state => state.count)
  return (
    <div>
      <h3>{count}</h3>
      <button
        onClick={() => {
          dispatch({ type: 'add', payload: 2 })
        }}
      >
        ++++
      </button>
    </div>
  )
}
export default App

2. Redux Toolkit

概述:

它开箱即用的高效 Redux 开发工具集,是 redux 新的库,也是官方推荐今后在项目中使用的 redux 库,内置了immer、redux-thunk和redux-devtools。

安装:

yarn add @reduxjs/toolkit react-redux

使用:

前台页面:

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
const App = () => {
  const dispatch = useDispatch()
  const count = useSelector(state => state.count)
  return (
    <div>
      <h3>{count}</h3>
      <button
        onClick={() => {
          dispatch({ type: 'add', payload: 2 })
        }}
      >
        ++++
      </button>
    </div>
  )
}
export default App

redux入口文件:

import { configureStore } from '@reduxjs/toolkit'
// 上来它就是分模块,在项目中,所以的数据一定是分模块来管理的
import count from './modules/count'
import user from './modules/users'
export default configureStore({
  reducer: {
    count,
    user
  }
})

同步操作(count.js):

import { createSlice } from '@reduxjs/toolkit'
// 同步操作
const countSlice = createSlice({
  // 命名空间名称,比redux中更好,redux没有
  // 它的名称要和入口文件中configureStore中的reducer配置对象中的key名称要一致
  name: 'count',
  // 初始化数据源
  initialState: {
    num: 10 
  },
  // 修改数据源的方法集合
  reducers: {
    // 组件中派发dispatch(setNum(2)) // 2就会给payload
    // state它就是proxy对象[immer]
    setNum(state, { payload }) {
      state.num += payload
    }
  }
})
// 导出给在组件中调用
export const { setNum } = countSlice.actions
// 把当前模块的reducer导入,集合到大的reducer中
export default countSlice.reducer

异步操作(users.js):

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
// 方案2
// 写在上面,进行网络请求
export const fetchUser = createAsyncThunk('user/fetchUser', async page => {
  // 实现异步数据获取
  let ret = await (await fetch('/api/users?page=' + page)).JSON()
  // return 中的数据就是返回到state中的users中的数据  一定要return
  return ret.data
})
// 异步操作
const userSlice = createSlice({
  name: 'user',
  initialState: {
    users: []
  },
  reducers: {
    setUsers(state, { payload }) {
      state.users = payload
    }
  },
  // 解决异步
  extraReducers: builder => {
    // 模拟了promise的3个状态,只取成功状态 fulfilled
    // payload中的数据就是fetchUser方法它return出来的数据
    builder.addCase(fetchUser.fulfilled, (state, { payload }) => {
      state.users = payload
    })
  }
})
export const { setUsers } = userSlice.actions
// 网络请求  --- 内置redux-thunk所以,就可以在此处完成异步操作  -- 我推荐的
// 方案1
export const fetchThunkUser = () => async dispatch => {
  let ret = await (await fetch('/api/users')).json()
  dispatch(setUsers(ret.data))
}
export default userSlice.reducer

到此这篇关于React immer与Redux Toolkit使用教程详解的文章就介绍到这了,更多相关React immer与Redux Toolkit内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Reactimmer与ReduxToolkit使用教程详解

本文链接: https://www.lsjlt.com/news/169601.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Reactimmer与ReduxToolkit使用教程详解
    目录1. immer1.1 setState结合immer使用1.2 useState结合immer使用1.3 immer和redux集合2. Redux Toolkit1. imm...
    99+
    2022-11-13
    React immer React Redux Toolkit
  • MySQL Workbench下载与使用教程详解
    一、MySQL Workbench的下载 Workbench是MySql图形化的管理工具,可以在Workbench里输入MySql的语句,这可能更适合大多数人的视觉,有些操作更能更简单化 首先我们下载wor...
    99+
    2022-10-18
  • React immer与Redux Toolkit使用教程详解
    目录1. immer1.1 setState结合immer使用1.2 useState结合immer使用1.3 immer和redux集合2. Redux Toolkit1. immer概述:它和immutable相似的,实现了操作对象的数...
    99+
    2022-10-21
  • 详解vue-socket.io使用教程与踩坑记录
    目录前言我遇到的问题使用教程安装引入(main.js)使用(Page.vue)解决方案结合connect事件+store+路由守卫实现拦截请先允许我狠狠吐个槽:vue-socket....
    99+
    2022-11-13
  • 详解supervisor使用教程
    A Process Control System 使用b/s架构、运行在类Unix系统上一个进程监控管理系统它可以使进程以daemon方式运行,并且一直监控进程,在意外退出时能自动重启进程。 安装 Supe...
    99+
    2022-06-04
    详解 教程 supervisor
  • yolov5中train.py代码注释详解与使用教程
    目录前言1. parse_opt函数2. main函数2.1 main函数——打印关键词/安装环境2.2 main函数——是否进行断点...
    99+
    2022-11-11
  • Windows下Redis x64的安装与使用教程详解
    目录1、概述2、Redis的下载3、Redis安装4、查看Redis使用情况5、设置密码6、测试Redis读写服务1、概述 Redis是一款内存高速缓存数据库。Redis全称为:Re...
    99+
    2022-11-13
  • Android Notification使用教程详解
    目录前言正文一、Android中通知的变化1. Android 4.1,API 162. Android 4.4,API 19 和 203. Android 5.0,API 214....
    99+
    2022-11-13
  • 详解MySQL Workbench使用教程
    MySQL Workbench 是一款专为 MySQL 设计的集成化桌面软件,也是下一代的可视化数据库设计、管理的工具,它同时有开源和商业化两个版本。该软件支持 Windows 和 Linux 系统,可以从 http...
    99+
    2022-05-30
    MySQL Workbench
  • TypeScript安装与使用的详细教程
    目录初识TypeScriptTypeScript给JS添加类型支持的原因TypeScript相比JS的优势TS工具包的安装TS文件的编译和运行简化TS的运行步骤附:查看ts版本、安装...
    99+
    2023-01-10
    ts安装 ts教程 typescript教程
  • Sqoop的安装与使用详细教程
    目录一、Sqoop的安装1.1 下载上传安装包1.2 修改配置文件1.3 拷贝JDBC驱动二、Sqoop的导入导出2.1 测试连接数据库2.2 MySQL导入数据到HDFS2.3 M...
    99+
    2022-11-12
  • CobaltStrike使用教程详解(基础)
    声明:本文仅限学习研究讨论,切忌做非法乱纪之事! 大家好,今天简单来聊聊CobaltStrike,这是我们后渗透阶段必不可少的神器。 Cobalt Strike 是一款流行的渗透测试工具,广泛用于红队操作和渗透测试。它由Raphael Mu...
    99+
    2023-09-13
    php 开发语言
  • @FeignClient使用详细教程(图解)
    @FeignClient使用详细教程图解 作用@FeignClient标签的常用属性使用流程通俗解释可以把它当成一个spring Bean 可以直接当成一个Service 给@FeignC...
    99+
    2023-10-12
    java spring
  • java中TestNG使用教程详解
    目录一、TestNG介绍二、TestNG安装(基于eclipse+maven)三、TestNG基本使用和运行1、直接运行:2、xml方式运行四、注解说明五、TestNG断言六、Tes...
    99+
    2022-11-12
  • CocoaPods1.9.0 安装使用教程详解
    CocoaPods是什么 CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是Coco...
    99+
    2022-05-27
    CocoaPods1.9.0 安装 使用
  • Golang接口使用教程详解
    目录前言一、概述二、接口类型2.1 接口的定义2.2 实现接口的条件2.3 为什么需要接口2.4 接口类型变量三、值接收者和指针接收者3.1 值接收者实现接口3.2 指针接收者实现接...
    99+
    2022-11-11
  • PythonBeautifulSoup模块使用教程详解
    目录一、模块简介二、方法利用1、引入模块2、几个简单的浏览结构化数据的方法三、具体利用1、获取拥有指定属性的标签2、获取标签的属性值3、获取标签中的内容4、stripped_stri...
    99+
    2023-02-24
    Python Beautiful Soup Python Beautiful Soup模块
  • mysql 数据备份与恢复使用详解(超完整详细教程)
    目录一、前言二、数据备份策略1、全备2、增备3、差异备份三、数据备份类型1、冷备2、热备3、温备四、前置准备五、mysqldump 数据备份命令使用1、命令格式2、案例演示3、其他重要参数选项补充六、mysqldump ...
    99+
    2022-11-21
    mysql 备份与恢复 mysql 数据恢复
  • MySQL事务与锁实例教程详解
    目录mysql事务和锁事务事务的控制语句事务隔离级别设置脏读不可重复读幻读锁机制InnoDB的行级锁锁实战死锁总结MySQL事务和锁 事务 说到关系型的数据库的事务,相信大家对四大特性都不陌生,分别是原子性、一致性、隔离...
    99+
    2022-11-05
  • Java MeteoInfo解析与绘图代码教程详解
    最近太忙了,终于有时间继续写了,上文说到了基本上的绘图方法,但缺少色阶呈现,一般图叠加着地图上,后端不需要管色阶,但也要注意web页面色阶和我们的生成色阶一定要对的上 对于后端导出图...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作