最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React immer與Redux Toolkit使用教程詳解

 更新時間:2022年10月18日 11:33:24   作者:月光曬了很涼快  
這篇文章主要介紹了React中immer與Redux Toolkit的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

1. immer

概述:

它和immutable相似的,實現(xiàn)了操作對象的數(shù)據(jù)共享,可以優(yōu)化性能。它實現(xiàn)的原理使用es6的Proxy完成的。小巧,沒有像immutable哪樣有新數(shù)據(jù)類型,而是使用js類型。

安裝:

yarn add immer@9

1.1 setState結(jié)合immer使用

簡單使用:

import React from 'react'
// 把源數(shù)據(jù)使用Proxy進行代理處理,后面就可以精準的去找到變化的數(shù)據(jù)
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代理,源數(shù)據(jù)中只有變化的了的數(shù)據(jù)才更新,沒有變化則共享,這樣做可以提高性能:

import React from 'react'
// 把源數(shù)據(jù)使用Proxy進行代理處理,后面就可以精準的去找到變化的數(shù)據(jù)
import { produce } from 'immer'
const baseState = {
  arr: [1, 2, 3],
  obj: { id: 1, name: '張三' }
}
// 使用immer進行proxy代理,源數(shù)據(jù)中只有變化的了的數(shù)據(jù)才更新,沒有變化則共享,提高性能
const newState = produce(baseState, draft => {
  draft.arr.push(4)
})
// 當前只修改數(shù)組,對象沒有修改,共享
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 優(yōu)化 setState 使用:

import React, { Component } from 'react'
import { produce } from 'immer'
// 優(yōu)化setState更新數(shù)據(jù)
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來優(yōu)化setState操作
    this.setState(
      produce(draft => {
        // 不用返回,返加不允許,draft它是一個代理對象,修改后,它能監(jiān)聽到數(shù)據(jù)的變化,更新視圖
        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結(jié)合immer使用

import React, { useState } from 'react'
import { produce } from 'immer'
const App = () => {
  // 普通的數(shù)字,不是proxy代理,proxy代理的是對象
  // 如果它是一個普通值,沒有必要使用immer來完成優(yōu)化操作
  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 = (state = initState, { type, payload }) => {
  if ('add' === type) {
    // 深復(fù)制
    return { ...state, count: state.count + payload }
  }
  return state
} */
const reducer = produce((draft, { type,  payload }) => {
  // 寫法就和vuex中的mutation中的寫法一樣的,簡化了
  // 操作數(shù)據(jù)無需深復(fù)制,提升性能
  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 開發(fā)工具集,是 redux 新的庫,也是官方推薦今后在項目中使用的 redux 庫,內(nèi)置了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'
// 上來它就是分模塊,在項目中,所以的數(shù)據(jù)一定是分模塊來管理的
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',
  // 初始化數(shù)據(jù)源
  initialState: {
    num: 10 
  },
  // 修改數(shù)據(jù)源的方法集合
  reducers: {
    // 組件中派發(fā)dispatch(setNum(2)) // 2就會給payload
    // state它就是proxy對象[immer]
    setNum(state, { payload }) {
      state.num += payload
    }
  }
})
// 導(dǎo)出給在組件中調(diào)用
export const { setNum } = countSlice.actions
// 把當前模塊的reducer導(dǎo)入,集合到大的reducer中
export default countSlice.reducer

異步操作(users.js):

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
// 方案2
// 寫在上面,進行網(wǎng)絡(luò)請求
export const fetchUser = createAsyncThunk('user/fetchUser', async page => {
  // 實現(xiàn)異步數(shù)據(jù)獲取
  let ret = await (await fetch('/api/users?page=' + page)).json()
  // return 中的數(shù)據(jù)就是返回到state中的users中的數(shù)據(jù)  一定要return
  return ret.data
})
// 異步操作
const userSlice = createSlice({
  name: 'user',
  initialState: {
    users: []
  },
  reducers: {
    setUsers(state, { payload }) {
      state.users = payload
    }
  },
  // 解決異步
  extraReducers: builder => {
    // 模擬了promise的3個狀態(tài),只取成功狀態(tài) fulfilled
    // payload中的數(shù)據(jù)就是fetchUser方法它return出來的數(shù)據(jù)
    builder.addCase(fetchUser.fulfilled, (state, { payload }) => {
      state.users = payload
    })
  }
})
export const { setUsers } = userSlice.actions
// 網(wǎng)絡(luò)請求  --- 內(nèi)置redux-thunk所以,就可以在此處完成異步操作  -- 我推薦的
// 方案1
export const fetchThunkUser = () => async dispatch => {
  let ret = await (await fetch('/api/users')).json()
  dispatch(setUsers(ret.data))
}
export default userSlice.reducer

到此這篇關(guān)于React immer與Redux Toolkit使用教程詳解的文章就介紹到這了,更多相關(guān)React immer與Redux Toolkit內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • react項目從新建到部署的實現(xiàn)示例

    react項目從新建到部署的實現(xiàn)示例

    這篇文章主要介紹了react項目從新建到部署的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • React學(xué)習(xí)筆記之事件處理(二)

    React學(xué)習(xí)筆記之事件處理(二)

    這篇文章主要跟大家介紹了關(guān)于React中事件處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)React具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • useCallback和useMemo的正確用法詳解

    useCallback和useMemo的正確用法詳解

    這篇文章主要為大家介紹了useCallback和useMemo的正確用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • React組件中按鈕的loading狀態(tài)失效問題的解決方案

    React組件中按鈕的loading狀態(tài)失效問題的解決方案

    在React開發(fā)過程中,我遇到這樣的情況:頁面按鈕的loading屬性失效,盡管通過useEffect打印發(fā)現(xiàn)loading狀態(tài)(確實在true和false之間切換,但按鈕卻沒有表現(xiàn)出預(yù)期的加載效果,所以本文給大家介紹了失效的解決方案,需要的朋友可以參考下
    2025-07-07
  • React.js前端導(dǎo)出Excel的方式

    React.js前端導(dǎo)出Excel的方式

    這篇文章主要為大家介紹了React.js前端導(dǎo)出Excel的方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 詳解如何使用React Hooks請求數(shù)據(jù)并渲染

    詳解如何使用React Hooks請求數(shù)據(jù)并渲染

    這篇文章主要介紹了如何使用React Hooks請求數(shù)據(jù)并渲染,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • react-dnd?API拖拽工具詳細用法示例

    react-dnd?API拖拽工具詳細用法示例

    這篇文章主要為大家介紹了react-dnd?API拖拽工具的詳細用法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 基于Node的React圖片上傳組件實現(xiàn)實例代碼

    基于Node的React圖片上傳組件實現(xiàn)實例代碼

    本篇文章主要介紹了基于Node的React圖片上傳組件實現(xiàn)實例代碼,非常具有實用價值,需要的朋友可以參考下
    2017-05-05
  • react源碼中的生命周期和事件系統(tǒng)實例解析

    react源碼中的生命周期和事件系統(tǒng)實例解析

    這篇文章主要為大家介紹了react源碼中的生命周期和事件系統(tǒng)實例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • React?中使用?react-i18next?國際化的過程(react-i18next?的基本用法)

    React?中使用?react-i18next?國際化的過程(react-i18next?的基本用法)

    i18next?是一款強大的國際化框架,react-i18next?是基于?i18next?適用于?React?的框架,本文介紹了?react-i18next?的基本用法,如果更特殊的需求,文章開頭的官方地址可以找到答案
    2023-01-01

最新評論

长兴县| 汤原县| 禹州市| 商南县| 灵武市| 绵竹市| 涞源县| 焦作市| 宁南县| 靖宇县| 宜昌市| 惠水县| 曲水县| 友谊县| 乌恰县| 新巴尔虎右旗| 文山县| 诸暨市| 临汾市| 上虞市| 潜山县| 霸州市| 湄潭县| 宁阳县| 洞头县| 乾安县| 崇文区| 龙门县| 常德市| 穆棱市| 任丘市| 阿荣旗| 香港| 蒙山县| 罗定市| 德清县| 仪陇县| 定南县| 湘潭县| 乌苏市| 车致|