Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
580 views
in Technique[技术] by (71.8m points)

javascript - 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. I have two variables that are hooked into my Redux store:

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(() => {
    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.

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:

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? Is there a different way to use Redux state in a dependency array? Thanks!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

Please log in or register to answer this question.

1 Answer

0 votes
by (71.8m points)

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 {}. and {} === {} // false

So ain your useEffect dependency array, it's each time a new Object, so useEffect is triggered.

So either remove your || {} in your selector (because null === null & undefined === undefined) or consider moving to useShallowSelector as explained in react-redux documentation


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
...