[英]How do I avoid infinite loop when using Redux state in useEffect dependency array?
I'm trying to figure out why my useEffect function ends up in an infinite loop.我试图弄清楚为什么我的 useEffect function 最终陷入无限循环。 I have two variables that are hooked into my Redux store:
我有两个变量连接到我的 Redux 存储中:
const vehicles: AllVehiclesCollection = useSelector((state: ReduxState) => state.claims?.vehicles ?? {});
const properties: AllPropertiesCollection = useSelector((state: ReduxState) => state.claims?.properties ?? {});
and I have an action that is dispatched to the store that updates these only after a user clicks a button.我有一个动作被发送到商店,只有在用户点击按钮后才会更新这些。
I have a useEffect that will trigger based on either of these variables changing.我有一个 useEffect 将根据这些变量中的任何一个变化而触发。
useEffect(() => {
let fullVehicleList: DropdownData[] = getFormattedVehicleListForDisplay();
let fullPropertyList: DropdownData[] = getFormattedPropertyListForDisplay();
let fullList = fullVehicleList.concat(fullPropertyList);
if (fullList.length > 0) {
setVehiclesAndPropertiesList(fullList);
} else {
setVehiclesAndPropertiesList(null);
}
}, [vehicles, properties]);
Nowhere in this code are the vehicles or properties variables changed or any actions dispatched that would change the Redux state.此代码中的任何地方都没有更改车辆或属性变量或调度任何会更改 Redux state 的操作。
getFormattedVehicleListForDisplay function: getFormattedVehicleListForDisplay function:
const getFormattedVehicleListForDisplay = () => {
let list: DropdownData[] = [];
if (Object.keys(vehicles).length > 0) {
let thisPolicysVehicles = [];
if (vehicles !== null) {
const key = `${selectedPolicy.symbol}${selectedPolicy.number}`;
thisPolicysVehicles = vehicles[key];
}
if (thisPolicysVehicles && thisPolicysVehicles.length > 0) {
thisPolicysVehicles.forEach((vehicle: VehicleInformation) => {
if (vehicle.vehicleMake !== OTHER_VEHICLE) {
list.push({
label: formatVehicleForDisplay(vehicle),
value: { ...vehicle, type: 'V' },
});
} else {
list.push({ label: vehicle.vehicleMake, value: {} });
}
});
}
}
return list;
};
getFormattedPropertyListForDisplay function: getFormattedPropertyListForDisplay function:
const getFormattedPropertyListForDisplay = () => {
let list: DropdownDataOMIG[] = [];
if (Object.keys(properties).length > 0) {
let thisPolicysProperties = [];
if (properties !== null) {
const key = `${selectedPolicy.symbol}${selectedPolicy.number}`;
thisPolicysProperties = properties[key];
}
if (thisPolicysProperties && thisPolicysProperties.length > 0) {
thisPolicysProperties.forEach((property: LocationInformation) => {
if (property.locStreet1 !== OTHER_PROP) {
list.push({
label: formatPropertyForDisplay(property),
value: { ...property, type: 'P' },
});
} else {
list.push({ label: property.locStreet1, value: {} });
}
});
}
}
return list;
};
For reference, the data in vehicles and properties is a set of key-value pairs where the key is a unique identifier of a given account number and the value is an array of vehicle/property objects for that account.作为参考,车辆和属性中的数据是一组键值对,其中键是给定帐号的唯一标识符,值是该帐户的车辆/属性对象数组。
Any idea why this goes into an infinite loop when using Redux state in the dependency array?知道为什么在依赖数组中使用 Redux state 时会进入无限循环吗? Is there a different way to use Redux state in a dependency array?
在依赖数组中使用 Redux state 有不同的方法吗? Thanks!
谢谢!
When using使用时
const vehicles = useSelector((state: ReduxState) => state.claims?.vehicles ?? {});
Each time this is triggered, and you don't have vehicles
in your store, you return a new object {}
.每次触发时,如果您的商店中没有
vehicles
,则返回一个新的 object {}
。 and {} === {} // false
和
{} === {} // false
So ain your useEffect
dependency array, it's each time a new Object, so useEffect is triggered.所以在你的
useEffect
依赖数组中,每次都是一个新的Object,所以触发了useEffect。
So either remove your || {}
所以要么删除你的
|| {}
|| {}
in your selector (because null === null
& undefined === undefined
) or consider moving to useShallowSelector
as explained in react-redux documentation || {}
在您的选择器中(因为null === null
& undefined === undefined
)或考虑按照Z1FFA815C34D64D742AB00D7346213902 文档中的说明移至useShallowSelector
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.