将整个对象传递给 redux reselect 选择器,但仅当一个 属性 对象更改时才更改它

Pass a whole object to redux reselect selector, but change it only if one property of the object changes

开始使用 Reselect,有一件事我似乎找不到答案。

假设我有一个帮手 fn (getVehicleList) 可以进行一些繁重的计算,所以我不希望它重新 运行 太多。我使用状态选择器来获取我需要的属性,例如:

const getVehicles = (state) => state.vehicles.vehicles;
const getVehicle = (state) => state.vehicles.vehicle;
const getUserId = (state) => state.auth.user.id;

然后我实施了 createSelector:

const getVehicles = createSelector(
  [getVehicles,
   getVehicle,
   getUserId],
  (vehicles, vehicle, id) => getVehicleList(
    vehicles,
    vehicle,
    id,
  ),
);

现在,vehicle returns 具有多个字段的对象。如果这些字段中的任何一个发生变化,对象就会发生变化,因此所有内容都会重新计算。有没有办法停止重新计算,直到 id 并且只有车辆的 ID 发生变化?

我尝试为 id 做一个状态选择器,比如

const getVehicle = (state) => state.vehicles.vehicle.id;

但这对我不起作用,因为我需要我的助手 fn 中的整个车辆对象,而不仅仅是 ID。

在此先感谢您的帮助!

您可以尝试以下方法:

const getVehicles = (state) => state.vehicles.vehicles;
const getVehicle = (state) => state.vehicles.vehicle;
const getUserId = (state) => state.auth.user.id;
const selectVhicleId = createSelector(
  [getVehicle],
  ({ id }) => id //return only the id
);
const selectVehicles = createSelector(
  [getVehicles, selectVhicleId, getUserId],
  (vehicles, vehicleId, id) =>
    getVehicleList(vehicles, { id: vehicleId }, id)
);

Here 是关于我如何在 React 中使用 reselect 的一些信息。

这是一个在 vehicle.id 发生变化(或任何其他依赖项)时重新计算车辆的示例。如果车辆的其他值发生变化,它不会重新计算,因此使用 getVehicleList 的车辆会获得传递给它的陈旧车辆,该车辆仅在 vehicle.id 更改时刷新:

const getVehicles = (state) => state.vehicles.vehicles;
const getVehicle = (state) => state.vehicles.vehicle;
const getUserId = (state) => state.auth.user.id;
const createSelectVehicles = (vehicle) =>
  createSelector([getVehicles, getUserId], (vehicles, id) =>
    getVehicleList(vehicles, vehicle, id)
  );

const Component = () => {
  //only re calculate vehicle if vehicle.id changes
  const vehicle = useSelector(
    getVehicle,
    (a, b) => a?.id === b?.id
  );
  //only create the selector when vehicle changes
  //  vehicle only changes when vehicle.id changes
  const selectVehicles = React.useMemo(
    () => createSelectVehicles(vehicle),
    [vehicle]
  );
  //vehicles is re calculated when vehicle.id changes
  //  or when state.vehicles.vehicles changes or
  //  when state.auth.user.id changes
  const vehicles = useSelector(selectVehicles);
};