如何在使用 redux/reselect 时防止组件重新渲染?
How to prevent component re-render while using 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;
}
);
希望这对以后的人有所帮助。
我经常收到我的状态更新,这导致组件中出现一些不需要的重新渲染,这些组件未访问不断变化的状态属性。
组件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;
}
);
希望这对以后的人有所帮助。