首页 > 解决方案 > 不一致的 Array.includes() 行为 - 相同的数组返回不同的结果

问题描述

谁能帮助解释 Array.includes() 的这种奇怪行为?

我更新了提供的信息以显示数组是如何构建的。我正在使用扩展运算符和过滤,据我所知,它们都会创建新副本。我这样做是因为我相信对于状态,您应该始终创建对象的新副本以免发生变异。我以为这就是你对 state 所做的事情。

来自 chrome 控制台的屏幕截图


要显示数组是如何构建的:


const PricingSection = ({
}) => {

  const [businessState, setBusinessState] = useState({
    purchase: {
      service: [],
      cost: []
    },
    subscription: {
      service: [],
      cost: []
    }
  });

  const [businessTotal, setBusinessTotal] = useState({
    purchase: [],
    subscription: []
  });

  useEffect(() => {
    const sumSubscriptionBusiness = businessState.subscription.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    const sumPurchaseBusiness = businessState.purchase.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    setBusinessTotal({
      purchase: sumPurchaseBusiness,
      subscription: sumSubscriptionBusiness
    });
  }, [businessState]);



  const [toggleValue, toggleHandler] = useToggle(isChecked);

  const handleChecking = (e, item) => {
    const { name } = e.target;
    const { id } = e.target;
    const newService = item.service;
    const newCost = item.cost;
    const newPCost = item.pcost;

    if (
      name === "business" &&
      businessState.subscription.service[0] !== undefined &&
      !businessState.subscription.service.includes(newService) &&
      !businessState.purchase.service.includes(newService)
    ) {

      const oldBusinessPurchaseService = businessState.purchase.service;
      const oldBusinessPurchaseCost = businessState.purchase.cost;
      const oldBusinessSubscriptionService = businessState.subscription.service;
      const oldBusinessSubscriptionCost = businessState.subscription.cost;
      setBusinessState({
        purchase: {
          service: [...oldBusinessPurchaseService, item.service],
          cost: [...oldBusinessPurchaseCost, newPCost]
        },
        subscription: {
          service: [...oldBusinessSubscriptionService, item.service],
          cost: [...oldBusinessSubscriptionCost, newCost]
        }
      });
    }
    if (
      name === "business" &&
      businessState.subscription.service[0] !== undefined &&
      businessState.subscription.service.includes(newService) |
        businessState.purchase.service.includes(newService)
    ) {
      const removeBusinessIndex = businessState.subscription.service.indexOf(
        newService
      );
      const reducedBusinessSubscriptionService = businessState.subscription.service.filter(
        (s, i) => i !== removeBusinessIndex
      );

      const reducedBusinessSubscriptionCost = businessState.subscription.cost.filter(
        (s, i) => i !== removeBusinessIndex
      );

      const reducedBusinessPurchaseService = businessState.purchase.service.filter(
        (s, i) => i !== removeBusinessIndex
      );

      const reducedBusinessPurchaseCost = businessState.purchase.cost.filter(
        (s, i) => i !== removeBusinessIndex
      );

      setBusinessState({
        purchase: {
          service: [...reducedBusinessPurchaseService],
          cost: [...reducedBusinessPurchaseCost]
        },
        subscription: {
          service: [...reducedBusinessSubscriptionService],
          cost: [...reducedBusinessSubscriptionCost]
        }
      });
    }
    if (
      name === "business" &&
      businessState.subscription.service[0] === undefined
    ) {
      setBusinessState({
        purchase: {
          service: [newService],
          cost: [newPCost]
        },
        subscription: {
          service: [newService],
          cost: [newCost]
        }
      });
    }

  };

  const data = state.data;
  const activeStatus = state.active;

  return (

                    <PricingList>
                      {pricingTable.listItems.map((item, index) => (
                        <ListItem key={`pricing-table-list-${index}`}>
                          <Checkbox
                            name={`${pricingTable.category}`}
                            id={`${pricingTable.type}`}
                            labelText={item.service}
                            checked={toggleValue}
                            value={item}
                            onChange={e => {
                              toggleHandler;
                              handleChecking(e, item);
                            }}

                          />

                        </ListItem>
                      ))}
                    </PricingList>
  );
};

export default PricingSection;

数据来自这里:

export const YEARLY_PRICING_TABLE = [
{
    name: "Business Website",
    category: "business",
    type: "purchase",
    description: "For Small teams or group who need to build website ",
    price: "$6.00",
    priceLabel: "Per month & subscription yearly",
    buttonLabel: "Register Now",
    url: "#",
    trialButtonLabel: "Or Start 14 Days trail",
    trialURL: "#",
    listItems: [
      {
        service: ["Mobile-ready, Responsive Design"],
        cost: [6],
        pcost: [600]
      },
      {
        service: ["Blog Articles"],
        cost: [14],
        pcost: [1300]
      },
      {
        service: ["Collect visitor information (email / phone)"],
        cost: [10],
        pcost: [1000]
      },
      {
        service: ["eCommerce Store "],
        cost: [25],
        pcost: [3200]
      },
      {
        service: ["30+ Webmaster Tools"],
        cost: [2],
        pcost: [500]
      }
    ]
  },
...
],
export const MONTHLY_PRICING_TABLE = [
{
    name: "Business Website",
    category: "business",
    type: "subscription",
    description: "Multi-page Website for Small-Large Businesses",
    price: "$9.87",
    priceLabel: "Per month & subscription yearly",
    buttonLabel: "Register Now",
    url: "#",
    trialButtonLabel: "Or Start 14 Days trail",
    trialURL: "#",
    listItems: [
      {
        service: ["Mobile-ready, Responsive Design"],
        cost: [6],
        pcost: [600]
      },
      {
        service: ["Blog Articles"],
        cost: [14],
        pcost: [1300]
      },
      {
        service: ["Collect visitor information (email / phone)"],
        cost: [10],
        pcost: [1000]
      },
      {
        service: ["eCommerce Store "],
        cost: [25],
        pcost: [3200]
      },
      {
        service: ["30+ Webmaster Tools"],
        cost: [2],
        pcost: [500]
      }
    ]
  },
]

标签: javascriptarrays

解决方案


2 件事要记住:

  • 数组是对象和
  • 对象的相等性基于相同的引用,而不仅仅是值。

let a = 3;
let b = 3;
console.log(a === b); // true

let aObj = {x: 3};
let bObj = {x: 3};
let cObj = aObj;
console.log(aObj === bObj); // false
console.log(aObj === cObj); // true


推荐阅读