Я работаю над некоторым унаследованным кодом, который раньше выполнял полное глубокое клонирование избыточного состояния в реактивном приложении.Вот исходный шаблон, который используется в качестве основы для редукторов, используемых в приложении:
export default (initialState, handlers = {}, promiseActionTypes = []) =>
(state = initialState, action) => {
let nextState = _.cloneDeep(state)
promiseActionTypes.forEach((actionType) => {
if (action.type === `@@REMOTE/${actionType}_REQUEST`) {
nextState.isFetching = true
}
if (action.type === `@@REMOTE/${actionType}_SUCCESS`) {
nextState = {
...nextState,
data: _.get(action, 'data.storeData', action.data),
isFetching: false,
isInited: true,
}
}
if (action.type === `@@REMOTE/${actionType}_FAILURE`) {
nextState.isFetching = false
}
})
if (handlers.hasOwnProperty(action.type)) {
nextState = handlers[action.type](nextState, action, _.cloneDeep(state))
}
return nextState
}
Все эти глубокие клоны - это большие запреты, поэтому я пытаюсь использовать функцию производства в immer для преобразованияподготовленные копии состояния перед возвратом в новое состояние.
Проблема в том, что я не смог получить все в синхронизации.Некоторые кусочки состояния не будут корректно обновляться здесь или там.Вот моя попытка рефакторинга до сих пор:
import produce from 'immer'
export default (initialState, handlers = {}, promiseActionTypes = []) =>
(state = initialState, action) => {
return produce(state, (draft) => {
promiseActionTypes.forEach((actionType) => {
if (action.type === `@@REMOTE/${actionType}_REQUEST`) {
draft.isFetching = true
}
if (action.type === `@@REMOTE/${actionType}_SUCCESS`) {
draft.data = _.get(action, 'data.storeData', action.data)
draft.isFetching = false
draft.isInited = true
}
if (action.type === `@@REMOTE/${actionType}_FAILURE`) {
draft.isFetching = false
}
return draft
})
if (handlers.hasOwnProperty(action.type)) {
return handlers[action.type](draft, action, state)
}
return draft
})
}
Я пытался разморозить затронутые объекты, но все еще не играл в кости.Моя реализация только что выключена?Или я неправильно понимаю, как работают продукты?
Черт, мне когда-нибудь нужно что-то вроде immer, если я просто пытаюсь получить оттуда эти два lodash cloneDeep
вызова?
РЕДАКТИРОВАТЬ:Вот пример пользовательского обработчика, который будет вызывать последнюю строку:
LOCATION_CHANGE: (state, action) => {
// bootstrap
if (_.isUndefined(state.location)) {
state.location = action.location
}
state.next = {
location: action.location,
changed: action.changed,
}
state.isNavigating = true
return state
},
VIEW_ROUTE_MATCH: (state, action) => {
state.next = {
...state.next,
match: action.match,
view: action.view,
}
return state
},