化简器中的复制状态导致速度缓慢



我有一个减速器,它给了我一些缓慢。我已经确定了克隆/复制我状态的一部分的步骤为慢速步骤。

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 个属性。我应该如何在保持最佳 Redux/React 实践的同时加快速度?

这是使用 Immer 编写不可变更新的用例。

手动编写不可变的更新逻辑通常很困难,并且容易出错。Immer 允许您使用"可变"逻辑编写更简单的不可变更新,甚至可以冻结开发中的状态以捕获应用程序中其他位置的突变。我们建议使用 Immer 编写不可变的更新逻辑,最好作为 Redux 工具包的一部分。

使用 Immer 草稿或任何不可变库,此类代码将变为:

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

它将修补状态并返回不可变数据。

请参阅Redux风格指南中的建议。

我认为复制是两次,第一次是在你声明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;
}
})
}
}

如果我尝试使用 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)

最新更新