Динамическая загрузка initialState с помощью createSlice в Redux Toolkit

Есть ли хорошо известный шаблон для внедрения полезной нагрузки динамического начального состояния в объект initialState Redux-Toolkit?

То есть я хотел бы сделать это -

import initialState from './initialState';

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

Например, {availableRooms: []} - это пустой массив, если он не введен при инициализации с данными {availableRooms: [{...}]}

Однако этот шаблон не работает, b / c я хочу экспортировать действия для отправки, что-то вроде этого:

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

export {actionName} from postsSlice.actions;

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

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

Я ограничен airbnb правилами линтинга, поэтому я не могу экспортировать на let -

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

export actions;

Функции, которые мне нужны, немного проще без использования createSlice. Причина моего вопроса в том, что я видел во многих местах, что createSlice рекомендуется вместо createAction + createReducer, но я не вижу простого способа представить динамические данные, которые я ищу.

Я ничего не знаю о redux-orm, но думаю, что функциональные возможности, которые мне нужны, аналогичны этот ТАК вопрос


person nrako    schedule 02.04.2020    source источник
comment
Привет, я в похожей ситуации. Удалось ли вам найти хороший способ сделать это?   -  person Tatsuya Yokota    schedule 02.12.2020
comment
Я не нашел способа использовать createSlice. Я опубликую код в качестве ответа на обходной путь, но меня интересуют другие / лучшие ответы.   -  person nrako    schedule 02.12.2020


Ответы (1)


Вот мой текущий обходной путь, который полностью пропускает createSlice.

В корневом рендере

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

И функция init (для краткости сокращена)

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;
}

В getInitialState я анализирую URL-адрес и настраиваю магазин в соответствии с бизнес-требованиями, смесью данных на стороне сервера и параметров, вводимых с помощью URL-адреса. Затем, в initDispatch, я вызываю store.dispatch() для некоторой логики инициализации, основанной на введенном начальном состоянии.

Здесь использование Typescript весьма полезно, поскольку оно обеспечивает соблюдение формы данных, возвращаемых из getInitialState, а также формы редукторов.

person nrako    schedule 02.12.2020