Next.js @reduxjs/toolkit redux-persist 之 6.0.0 版本持久化处理

集成公共状态管理插件

@reduxjs/toolkit react-redux redux-persist

store 之 index.ts 代码

import { configureStore } from '@reduxjs/toolkit'
import { useSelector, TypedUseSelectorHook, useDispatch, shallowEqual } from 'react-redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'

// 引入一个新的 reducer
import reducers from './reducers'

// 这个是redux-persist 的配置,可以配置黑名单、白名单
const persistConfig = {
  key: 'root', // 自动框架生产的根目录id 是root。不变
  storage, // 这个是选择用什么存储,session 还是 storage
}

// 一个经过处理的reducer
const persistedReducer = persistReducer(persistConfig, reducers)

// 获取值的类型
type GetStateFnType = typeof store.getState
type IRootState = ReturnType<GetStateFnType>
type DispatchType = typeof store.dispatch

// 创建 store
export const store = configureStore({
  reducer: persistedReducer,
  // 无法序列化
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false,
    }),
})
// 返回持久化对象
export const persistor = persistStore(store)
// 获取值
export const useAppSelector: TypedUseSelectorHook<IRootState> = useSelector
// 调用 dispatch 使用方法
export const useAppDispatch: () => DispatchType = useDispatch
// 进行值得浅层对比。如果值一样,就不更新值
export const useAppShallowEqual = shallowEqual


reducers 代码

import { combineReducers } from 'redux';
import globalReducer from '../modules/global'

export default combineReducers({
  global: globalReducer
});

global 代码

import { createSlice, PayloadAction } from '@reduxjs/toolkit'

const globalSlice = createSlice({
  name: 'global',
  initialState: {
    currentUrl: '/sound',
  },
  reducers: {
    changeCurrenttAction(state, { payload }: PayloadAction<string>) {
      state.currentUrl = payload
    },
  },
})

export const { changeCurrenttAction } = globalSlice.actions
export default globalSlice.reducer

Layout 文件代码 === app.tsx 代码

  • 从 redux-persist/integration/react 引入 PersistGate , 传递 persistor 文件
import React, { memo, Suspense } from 'react'
import type { FC, ReactNode } from 'react'
import { ThemeProvider } from 'styled-components'
import { Provider } from 'react-redux'

import { PersistGate } from 'redux-persist/integration/react'
import theme from '@/styles/theme'
import { LayoutWrapper } from './style'
import { store, persistor } from '../../store'
import AppHeader from '../app-header/index'
import AppFooter from '../app-footer/index'

interface IProps {
  children?: ReactNode
}

const Layout: FC<IProps> = ({ children }) => {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <ThemeProvider theme={theme}>
          <LayoutWrapper style={{ overflowX: 'hidden' }}>
            <AppHeader />
            <Suspense fallback={<AppHeader />}>
              <main className="container">{children}</main>
            </Suspense>
            <AppFooter />
          </LayoutWrapper>
        </ThemeProvider>
      </PersistGate>
    </Provider>
  )
}

// memo防止重复渲染
export default memo(Layout)

使用

import { useAppShallowEqual, useAppSelector, useAppDispatch } from '@/store'
import { changeCurrenttAction } from '@/store/modules/global'

  // redux 数据
  const { global: {currentUrl} } = useAppSelector((state) => state, useAppShallowEqual)

  const userDispatch = useAppDispatch()

  const handleUrl = (url: string): void => {
    Router.push({
      pathname: url,
    })
    // 使用 redux 方法
    userDispatch(changeCurrenttAction(url))
  }
posted @ 2023-01-31 15:26  DL·Coder  阅读(593)  评论(0编辑  收藏  举报