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

redux持久化之redux-persist結合immutable使用問題

 更新時間:2022年08月17日 16:28:02   作者:vs心動  
這篇文章主要為大家介紹了redux持久化之redux-persist結合immutable使用問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

最近學習了redux以及react-redux的結合使用確實讓redux在react中更好的輸出代碼啦~

但是考慮到項目的各種需求,我們還是需要對redux進行深一步的改造,讓其能更好的滿足我們的日常開發(fā),大大提高我們的開發(fā)效率。

今天給大家推薦兩個好用的功能包,并解決一個它們結合使用存在的問題。

redux-persist

redux-persist 主要用于幫助我們實現(xiàn)redux的狀態(tài)持久化

所謂狀態(tài)持久化就是將狀態(tài)與本地存儲聯(lián)系起來,達到刷新或者關閉重新打開后依然能得到保存的狀態(tài)。

安裝

yarn add redux-persist 
// 或者
npm i redux-persist

Github 地址 https://github.com/rt2zz/redux-persist

大家可以去看看官方的說明文檔,這里就不一一介紹功能了,簡單講一點常用功能和導入到項目使用。

使用到項目上

store.js

帶有 // ** 標識注釋的就是需要安裝后添加進去使用的一些配置,大家好好對比下投擲哦

下面文件也是一樣

import { createStore, applyMiddleware, compose } from "redux";
import thunk from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist' // **
import storage from 'redux-persist/lib/storage' // **
import reducer from './reducer'
const persistConfig = {  // **
    key: 'root',// 儲存的標識名
    storage, // 儲存方式
    whitelist: ['persistReducer'] //白名單 模塊參與緩存
}
const persistedReducer = persistReducer(persistConfig, reducer) // **
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(thunk))) // **
const persistor = persistStore(store) // **
export { // **
    store,
    persistor
}

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import { PersistGate } from 'redux-persist/integration/react' // **
import { store, persistor } from './store' // **
import 'antd/dist/antd.min.css';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}> 
    {/*  使用PersistGate //**   */}
      <PersistGate loading={null} persistor={persistor}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </PersistGate>
    </Provider>
  </React.StrictMode>
);

persist_reducer.js

注意此時的模塊是在白名單之內,這樣persist_reducer的狀態(tài)就會進行持久化處理了

import { DECREMENT } from './constant'
const defaultState = ({
    count: 1000,
    title: 'redux 持久化測試'
})
const reducer = (preState = defaultState, actions) => {
    const { type, count } = actions
    switch (type) {
        case DECREMENT:
             return { ...preState, count: preState.count - count * 1 }
        default:
            return preState
    }
}
export default reducer

這樣就可以使用起來了,更多的配置可以看看上面Github的地址上的說明文檔

immutable

immutable 主要配合我們redux的狀態(tài)來使用,因為reducer必須保證是一個純函數(shù),所以我們當狀態(tài)中有引用類型的值時我們可能進行淺拷貝來處理,或者遇到深層次的引用類型嵌套時我們采用深拷貝來處理。

但是我們會覺得這樣的處理確實稍微麻煩,而且我們若是采用簡單的深拷貝 JSON.parse JSON.stringify 來處理也是不靠譜的,存在缺陷 就比如屬性值為undefined 時會忽略該屬性。

所以 immutable 就是來幫我們解決這些問題,使用它修改后會到的一個新的引用地址,且它并不是完全復制的,它會盡可能的利用到未修改的引用地址來進行復用,比起傳統(tǒng)的深拷貝性能確實好很多。

這里就不多說了,想要了解更多可以看看下面的GitHub官網說明文檔。

安裝

npm install immutable
// 或者
yarn add immutable

GitHub地址 https://github.com/immutable-js/immutable-js

使用到項目上

count_reducer.js

import { INCREMENT } from './constant'
import { Map } from 'immutable'
// 簡單的結構用Map就行 復雜使用fromJs 讀取和設置都可以getIn setIn ...
const defaultState = Map({ // **
    count: 0,
    title: '計算求和案例'
})
const reducer = (preState = defaultState, actions) => {
    const { type, count } = actions
    switch (type) {
        case INCREMENT:
            // return { ...preState, count: preState.count + count * 1 }
            return preState.set('count', preState.get('count') + count * 1) // **
        default:
            return preState
    }
}
export default reducer

讀取和派發(fā)如下 : 派發(fā)無需變化,就是取值時需要get

函數(shù)組件

    const dispatch = useDispatch()
    const { count, title } = useSelector(state => ({
        count: state.countReducer.get("count"),
        title: state.countReducer.get("title")
    }), shallowEqual)
    const handleAdd = () => {
        const { value } = inputRef.current
        dispatch(incrementAction(value))
    }
    const handleAddAsync = () => {
        const { value } = inputRef.current
        dispatch(incrementAsyncAction(value, 2000))
    }

類組件

class RedexTest extends Component {
    // ....略
    render() {
        const { count, title } = this.props
        return (
            <div>
                <h2>Redux-test:{title}</h2>
                <h3>count:{count}</h3>
                <input type="text" ref={r => this.inputRef = r} />
                <button onClick={this.handleAdd}>+++</button>
                <button onClick={this.handleAddAsync}>asyncAdd</button>
            </div>
        )
    }
}
//使用connect()()創(chuàng)建并暴露一個Count的容器組件
export default connect(
    state => ({
        count: state.countReducer.get('count'),
        title: state.countReducer.get('title')
    }),
    {
        incrementAdd: incrementAction,
        incrementAsyncAdd: incrementAsyncAction
    }
)(RedexTest)

這樣就可以使用起來了,更多的配置可以看看上面Github的地址上的說明文檔

結合使用存在的問題

結合使用有一個坑?。?!

是這樣的,當我們使用了redux-persist 它會每次對我們的狀態(tài)保存到本地并返回給我們,但是如果使用了immutable進行處理,把默認狀態(tài)改成一種它內部定制Map結構,此時我們再傳給 redux-persist,它倒是不挑食能解析,但是它返回的結構變了,不再是之前那個Map結構了而是普通的對象,所以此時我們再在reducer操作它時就報錯了

如下案例:

組件

import React, { memo } from "react";
import { useDispatch, useSelector, shallowEqual } from "react-redux";
import { incrementAdd } from "../store/persist_action";
const ReduxPersist = memo(() => {
  const dispatch = useDispatch();
  const { count, title } = useSelector(
    ({ persistReducer }) => ({
      count: persistReducer.get("count"),
      title: persistReducer.get("title"),
    }),
    shallowEqual
  );
  return (
    <div>
      <h2>ReduxPersist----{title}</h2>
      <h3>count:{count}</h3>
      <button onClick={(e) => dispatch(incrementAdd(10))}>-10</button>
    </div>
  );
});
export default ReduxPersist;

persist-reducer.js

import { DECREMENT } from './constant'
import { fromJS } from 'immutable'
const defaultState = fromJS({
    count: 1000,
    title: 'redux 持久化測試'
})
const reducer = (preState = defaultState, actions) =&gt; {
    const { type, count } = actions
    switch (type) {
        case DECREMENT:
            return preState.set('count', preState.get('count') - count * 1)
        default:
            return preState
    }
}
export default reducer

按理說是正常顯示,但是呢由于該reducer是被redux-persist處理的,所以呢就報錯了

報錯提示我們沒有這個 get 方法了,即表示變成了普通對象

解決

組件

import React, { memo } from "react";
import { useDispatch, useSelector, shallowEqual } from "react-redux";
import { incrementAdd } from "../store/persist_action";
const ReduxPersist = memo(() => {
  const dispatch = useDispatch();
  // **
  const { count, title } = useSelector(
    ({ persistReducer: { count, title } }) => ({
      count,
      title,
    }),
    shallowEqual
  );
  //const { count, title } = useSelector(
  //  ({ persistReducer }) => ({
  //   count: persistReducer.get("count"),
  //    title: persistReducer.get("title"),
  //  }),
  //  shallowEqual
  // );
  return (
    <div>
      <h2>ReduxPersist----{title}</h2>
      <h3>count:{count}</h3>
      <button onClick={(e) => dispatch(incrementAdd(10))}>-10</button>
    </div>
  );
});
export default ReduxPersist;

persist-reducer.js

import { DECREMENT } from './constant'
import { fromJS } from 'immutable'
const defaultState = ({ // **
    count: 1000,
    title: 'redux 持久化測試'
})
const reducer = (preState = defaultState, actions) => {
    const { type, count } = actions
    let mapObj = fromJS(preState) // **
    switch (type) {
        case DECREMENT:
            // return preState.set('count', preState.get('count') - count * 1) 
            return mapObj.set('count', mapObj.get('count') - count * 1).toJS() // **
        default:
            return preState
    }
}
export default reducer

解決思路

由于 redux-persist 處理每次會返回普通對象,所以我們只能等要在reducer中處理狀態(tài)時,我們先將其用immutable處理成它內部定制Map結構,然后我們再進行set操作修改,最后我們又將Map結構轉換為普通對象輸出,這樣就完美的解決了這個問題。

以上就是redux持久化之redux-persist結合immutable使用問題的詳細內容,更多關于redux持久化redux-persist的資料請關注腳本之家其它相關文章!

相關文章

  • 優(yōu)雅的在React項目中使用Redux的方法

    優(yōu)雅的在React項目中使用Redux的方法

    這篇文章主要介紹了優(yōu)雅的在React項目中使用Redux的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 淺談React組件在什么情況下會重新渲染

    淺談React組件在什么情況下會重新渲染

    當我們使用React編寫組件時,組件的重新渲染是一個重要的概念,本文主要介紹了React組件在什么情況下會重新渲染,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 關于react useState更新異步問題

    關于react useState更新異步問題

    這篇文章主要介紹了關于react useState更新異步問題,具有很好的參考價值,希望對大家有所幫助。以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

    2022-08-08
  • React-router4路由監(jiān)聽的實現(xiàn)

    React-router4路由監(jiān)聽的實現(xiàn)

    這篇文章主要介紹了React-router4路由監(jiān)聽的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • React中Refs的使用場景及核心要點詳解

    React中Refs的使用場景及核心要點詳解

    在使用?React?進行開發(fā)過程中,或多或少使用過?Refs?進行?DOM?操作,這篇文章主要介紹了?Refs?功能和使用場景以及注意事項,希望對大家有所幫助
    2023-07-07
  • React-Native之定時器Timer的實現(xiàn)代碼

    React-Native之定時器Timer的實現(xiàn)代碼

    本篇文章主要介紹了React-Native之定時器Timer的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • React中使用Redux Toolkit狀態(tài)管理的示例詳解

    React中使用Redux Toolkit狀態(tài)管理的示例詳解

    在現(xiàn)代 React 應用程序中,狀態(tài)管理是一個至關重要的部分,使用 Redux Toolkit 可以簡化 Redux 的配置和管理,本文將通過三個文件的示例,詳細講解如何使用 Redux Toolkit 創(chuàng)建和管理一個簡單的計數(shù)器狀態(tài),需要的朋友可以參考下
    2024-11-11
  • React技巧之中斷map循環(huán)的方法詳解

    React技巧之中斷map循環(huán)的方法詳解

    這篇文章主要和大家來分享一下React的技巧之如何中斷map循環(huán),文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2023-06-06
  • react+antd實現(xiàn)動態(tài)編輯表格數(shù)據(jù)

    react+antd實現(xiàn)動態(tài)編輯表格數(shù)據(jù)

    這篇文章主要為大家詳細介紹了react+antd實現(xiàn)動態(tài)編輯表格數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React18新增特性介紹

    React18新增特性介紹

    react歷次版本迭代主要想解決的是兩類導致網頁卡頓的問題,分別是cpu密集型任務和io密集型任務導致的卡頓問題,react18新增特性就是為了解決上述問題
    2022-09-09

最新評論

仪陇县| 黔南| 玉屏| 老河口市| 宿迁市| 漠河县| 正安县| 青田县| 河东区| 太湖县| 额济纳旗| 文成县| 甘洛县| 泸西县| 锡林浩特市| 丽水市| 祁阳县| 武胜县| 东兴市| 霍城县| 揭西县| 忻城县| 桂平市| 明光市| 额敏县| 天全县| 响水县| 宣武区| 彭山县| 东丽区| 唐河县| 西贡区| 揭东县| 河东区| 霍山县| 台北市| 睢宁县| 丰顺县| 岢岚县| 项城市| 信宜市|