reactjs - 使用 redux/reselect 时如何防止组件重新渲染?
问题描述
我收到了对我的状态的频繁更新,这会导致在未访问不断变化的状态属性的组件中出现一些不需要的重新渲染。
组件 A 和 B 的创建方式相同,组件 A 具有 valueKeys ['speed', 'time'],组件 B 没有 valueKeys []。
当速度和时间更新时,每个数组都会再添加一个值,组件 A 会按预期重新渲染,但组件 B 也会重新渲染。
我认为这是因为 makeValuesSelector 参考的 valuesSelector 输入正在改变?尽管该值是一个空数组。
有什么办法可以防止组件 B 在这种情况下重新渲染?
状态
{
speed: [ 5, 4, 6],
time: [ 1, 2, 3]
}
值键
[ 'speed', 'time']
选择器
const valuesSelector = state => state.values;
const keysSelector= (state, props) => props.valueKeys;
const makeValuesSelector = () =>
createSelector(
[valuesSelector, keysSelector],
(values, keys) => {
let usedValues = {};
keys.forEach(key => {
if (values[key]) {
usedValues[key] = values[key];
}
});
return usedValues;
}
);
零件
const makeMapStateToProps = () => {
const valuesSelector = makeValuesSelector();
const mapStateToProps = (state, props) => ({
values: valuesSelector(state, props),
});
return mapStateToProps;
};
解决方案
一段时间后,我又回到了这个问题,因为它造成了严重的性能瓶颈。我通过在选择器中使用自定义相等检查来检查状态内的对象是否已更改,从而解决了这个问题。
如果组件需要的对象内部状态没有改变,则 makeValuesSelector 将不会运行,因为自定义相等检查阻止了它。由于 makeValuesSelector 尚未运行,因此它将阻止组件重新渲染。关于我上面描述的情况,组件 B 不会重新渲染。
const valuesSelector = state => state.values;
const keysSelector= (state, props) => props.valueKeys;
const equalityCheckShallow = (currentVal, previousVal) => {
let noUpdate = true;
Object.keys(currentVal).forEach(key => {
if (currentVal[key] !== previousVal[key]) {
noUpdate = false;
}
});
return noUpdate;
};
const createSelectorWithShallowCompare = createSelectorCreator(defaultMemoize, equalityCheckShallow);
const makeValuesSelector = () =>
createSelectorWithShallowCompare(
[valuesSelector, keysSelector],
(values, keys) => {
let usedValues = {};
keys.forEach(key => {
if (values[key]) {
usedValues[key] = values[key];
}
});
return usedValues;
}
);
希望这可以帮助将来的人。
推荐阅读
- python - 检查字符串列表是否包含来自另一个列表的字母
- angular - 角度转换日期
- python - 如何在python中从多个自变量和一个因变量绘制图形[多元线性回归]
- regex - re.sub 如何一步完成?
- php - 如何在服务器上的特定时间后运行 PHP 函数?
- javascript - 使用 Vue.js 更改元标题和描述
- php - 如何在应用程序\命令脚本的测试\单元脚本中包含一个特征?
- powershell - 在 ps1 工具中启动 ps1 文件
- postfix-mta - 作为 SMTP 中继的 Postfix 对 GMail 来说似乎不安全
- r - 聚合相同但针对单个列的行