本文介绍了在 Redux Toolkit 中使用 createSlice 动态加载 initialState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有众所周知的模式将动态初始状态的负载注入 Redux-Toolkit 的 initialState 对象?

也就是说,我想这样做 -

import initialState from './initialState';函数 generateSlice(payload = {}){const postsSlice = createSlice({name: '帖子',initialState: {...initialState, ...payload},///在这里注入数据减速器:{...}})}

例如,{availableRooms: []} 是一个空数组,除非在初始化时注入数据 {availableRooms: [{...}]}>

这种模式不起作用,但是,b/c 我想导出可调度的操作,就像这样-

 const postsSlice = createSlice({name: '帖子',initialState: {...initialState, ...payload},减速器:{...}})从postsSlice.actions 导出{actionName};*****从../mySlice"导入 {actionName}...const dispatch = useDispatch();dispatch(actionName('exampleVal'));...

我受到 airbnb linting 规则的限制,所以我不能在 let 上导出 -

let 动作;///坏的函数 generateSlice(payload){const postsSlice = createSlice({name: '帖子',initialState: {...initialState, ...payload},减速器:{...}})动作 = postsSlict.actions}出口行动;

如果不使用 createSlice,我所追求的功能会更容易一些.我的问题的原因是我在多个地方看到 createSlicecreateAction + createReducer 被推荐,但我没有看到任何介绍我要找的动态数据的简单方法.

我对 redux-orm 一无所知,但我认为我所追求的功能类似于 这个问题

解决方案

这是我目前的解决方法,它完全跳过了 createSlice.

在根渲染中

...const store = initStore(data);<提供者商店={商店}><应用程序/></提供者>

还有 init 函数(为简洁起见已缩减)

import {配置商店,获取默认中间件,结合减速器,来自'@reduxjs/toolkit';从@reservation/reducer"导入reservationReducer;从@map/reducer"导入 spaceHierarchyReducer;从@app/reducer"导入 appStoreReducer;让 ReduxStore;函数 initStore(ssrState:部分= {},){如果(ReduxStore){返回 ReduxStore;}const 切片 = {预订:reservationReducer,spaceHierarchy: spaceHierarchyReducer,应用商店:appStoreReducer,};const reducer = combineReducers(slices);const preloadedState = getInitialState(ssrState);const store = configureStore({减速器,中间件,预加载状态,});ReduxStore = 商店;initDispatch(商店);退货商店;}

getInitialState 中,我解析 URL 并根据业务需求设置存储,服务器端数据 + url-injectable 参数的混合.然后,在 initDispatch 中,我为一些基于注入初始状态的初始化逻辑调用 store.dispatch().

这里使用 Typescript 非常有用,因为它强制从 getInitialState 返回的数据的形状以及减速器的形状.

Is there a well-known pattern for injecting a payload of dynamic initial state into Redux-Toolkit's initialState object?

That is, I would like to do this -

import initialState from './initialState';

function generateSlice(payload = {}){
  const postsSlice = createSlice({
    name: 'posts',
    initialState: {...initialState, ...payload}, /// inject data here
    reducers: {...}
  })
}

For example, {availableRooms: []} is an empty array, unless injected on init with data {availableRooms: [{...}]}

This pattern doesn't work, however, b/c I want to export actions to be dispatch-able, something like this-

 const postsSlice = createSlice({
    name: 'posts',
    initialState: {...initialState, ...payload},
    reducers: {...}
  })

export {actionName} from postsSlice.actions;

*****
import {actionName} from '../mySlice'

...
const dispatch = useDispatch();
dispatch(actionName('exampleVal'));
...

I am constrained by the airbnb linting rules, so I can't export on let -

let actions; ///Bad
function generateSlice(payload){
  const postsSlice = createSlice({
    name: 'posts',
    initialState: {...initialState, ...payload},
    reducers: {...}
  })
  actions = postsSlict.actions
}

export actions;

The functionality that I am after is a bit easier without using createSlice. The reason for my question is that I have seen in multiple places that createSlice is recommended over createAction + createReducer, but I don't see any simple way to introduce the dynamic data that I am looking for.

I don't know anything about redux-orm but I think the functionality that I am after is similar to this SO question

解决方案

Here's my current work-around, which skips createSlice altogether.

In the root render

...
const store = initStore(data);
 <Provider store={store}>
  <App />
</Provider>

And the init function (pared down for brevity)

import {
  configureStore,
  getDefaultMiddleware,
  combineReducers,
} from '@reduxjs/toolkit';
import reservationReducer from '@reservation/reducer';
import spaceHierarchyReducer from '@map/reducer';
import appStoreReducer from '@app/reducer';

let ReduxStore;

function initStore(
  ssrState: Partial<RootStore> = {},
) {
  if (ReduxStore) {
    return ReduxStore;
  }
  const slices = {
    reservation: reservationReducer,
    spaceHierarchy: spaceHierarchyReducer,
    appStore: appStoreReducer,
  };
  const reducer = combineReducers(slices);
  const preloadedState = getInitialState(ssrState);
  const store = configureStore({
    reducer,
    middleware,
    preloadedState,
  });

  ReduxStore = store;
  initDispatch(store);
  return store;
}

In getInitialState, I parse the URL and set-up the store based on business requirements, a mixture of server-side data + url-injectable params. Then, in initDispatch, I invoke store.dispatch() for some init logic based that injected initial state.

Here the usage of Typescript is quite helpful, as it enforces the shape of the data returned from getInitialState as well as the shape of the reducers.

这篇关于在 Redux Toolkit 中使用 createSlice 动态加载 initialState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-30 00:47