Копирование состояния в редукторе вызывает замедление - PullRequest
1 голос
/ 18 июня 2020

У меня есть редуктор, который немного тормозит. Я определил шаг, который клонирует / копирует часть моего состояния, как медленный шаг.

export default function itemReducer(state = initialState, action) {
   case ITEM_FETCH_IMPACT_UPDATE:
        {
            let index = action.payload.index
slow step-> let items = [...state.items]; 
            items[index] = {...items[index], overallIsLoading: true};
            return {...state, items}
        };
}

items - довольно большой массив из примерно 300 объектов, каждый из которых имеет ~ 10 свойств. Как мне go ускорить это, сохранив при этом лучшие практики Redux / React?

Ответы [ 3 ]

2 голосов
/ 18 июня 2020

Это вариант использования Immer для записи неизменяемых обновлений .

Написание неизменяемых logi обновлений c вручную часто затруднительно и подвержено ошибкам. Immer позволяет вам писать более простые неизменяемые обновления, используя «изменяющуюся» логику c, и даже замораживает ваше состояние в процессе разработки, чтобы уловить мутации в другом месте приложения. Мы рекомендуем использовать Immer для написания неизменяемого журнала обновлений c, желательно как часть Redux Toolkit .

с черновиками Immer или любой неизменяемой библиотекой, такой код станет:

const index = action.payload.index;
state.items[index].overallIsLoading = true;

И он исправит состояние и вернет неизменяемые данные.

См. рекомендацию Руководство по стилю Redux .

0 голосов
/ 18 июня 2020

Если я попробую этот код с 3000 элементами, он все равно будет работать за микросекунды. Я не уверен, что вы правильно определили проблему или просто ввели неправильный код.

const a = new Array(3000).fill('').map(() =>
  (
    'abcdefghijklmnopqrstuvwxyz1' +
    '234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  )
    .split('')
    .reduce((result, key) => {
      result[key] = Math.random();
      return result;
    }, {})
);
const now = performance.now();
const b = [...a]
const c = [...a]
const d = [...a]
const e = [...a]
const f = [...a]
console.log('that took:',performance.now()-now)
0 голосов
/ 18 июня 2020

Я думаю, что копирование выполняется дважды: в первый раз, когда вы объявляете items, затем, когда вы возвращаете новое состояние.

Если разделение самого состояния не является жизнеспособным вариантом, то я предлагаю уменьшить количество копий до одного:

export default function itemReducer(state = initialState, action) {
  case ITEM_FETCH_IMPACT_UPDATE:
     return {
       ...state,
       items: state.items.map((item, ind) => {
         if(ind===action.payload.index){
           return {
             ...item,
             overallIsLoading:true
           }
         } else {
           return item;
         }
       })
     }
}
...