性能问题-React Hooks useEffect

时间:2020-02-24 18:43:47

标签: javascript reactjs react-hooks use-effect

我遇到了性能问题。我不确定是否是因为我使用了多个useEffect(我试图通过让他们观看相关状态来限制他们的行为)?

或者也许是因为我使用了一堆if语句?还是我正在执行的所有过滤器?

目标是使用户能够检查和取消检查不同的功能,并计算得出的价格。计算的价格会根据所选的选项(年度/订阅)而有所不同。

您可以在这里看到问题:https://prisma2-frontend-project.now.sh/

如果您向下滚动到“定价”部分,则可以看到,如果您开始选择和取消选择一个或两个复选框,那实际上不是问题。但是,当您开始做更多事情或切换到“购买”标签时,事情开始真正陷入困境。数学甚至开始变得奇怪!哈哈

相关代码:

import React, { useState, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import Link from "next/link";
import Box from "reusecore/src/elements/Box";
import Text from "reusecore/src/elements/Text";
import Heading from "reusecore/src/elements/Heading";
import Checkbox from "reusecore/src/elements/Checkbox";
import Button from "reusecore/src/elements/Button";
import Container from "common/src/components/UI/Container";
import GlideCarousel from "common/src/components/GlideCarousel";
import GlideSlide from "common/src/components/GlideCarousel/glideSlide";
import { useToggle } from "reusecore/src/hooks";

import {
  MONTHLY_PRICING_TABLE,
  YEARLY_PRICING_TABLE
} from "common/src/data/SaasClassic";

import PricingTable, {
  PricingHead,
  PricingPrice,
  PricingButton,
  PricingList,
  ListItem,
  PricingButtonWrapper,
  PricingTableWrapper
} from "./pricing.style";

const PricingSection = ({
  sectionWrapper,
  isChecked,
  secTitleWrapper,
  secHeading,
  secText,
  nameStyle,
  descriptionStyle,
  priceStyle,
  priceLabelStyle,
  buttonFillStyle,
  listContentStyle
}) => {
  const [state, setState] = useState({
    data: MONTHLY_PRICING_TABLE,
    active: true
  });

  const [loading, setLoading] = useState(false);

  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);

  useEffect(() => {
    const sumSubscriptionInformation = informationState.subscription.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    const sumPurchaseInformation = informationState.purchase.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    setInformationTotal({
      purchase: sumPurchaseInformation,
      subscription: sumSubscriptionInformation
    });
  }, informationState);

  useEffect(() => {
    const sumSubscriptionEcommerce = ecommerceState.subscription.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    const sumPurchaseEcommerce = ecommerceState.purchase.cost.reduce(
      (total, next) => total + Number(next),
      0
    );
    setEcommerceTotal({
      purchase: sumPurchaseEcommerce,
      subscription: sumSubscriptionEcommerce
    });
  }, ecommerceState);

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

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

  const [informationState, setInformationState] = useState({
    purchase: {
      service: [],
      cost: []
    },
    subscription: {
      service: [],
      cost: []
    }
  });
  const [ecommerceState, setEcommerceState] = useState({
    purchase: {
      service: [],
      cost: []
    },
    subscription: {
      service: [],
      cost: []
    }
  });

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

  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 &&
      !Object.values(businessState.subscription.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, newService],
          cost: [...oldBusinessPurchaseCost, newPCost]
        },
        subscription: {
          service: [...oldBusinessSubscriptionService, newService],
          cost: [...oldBusinessSubscriptionCost, newCost]
        }
      });
    }
    if (
      name === "business" &&
      businessState.subscription.service[0] !== undefined &&
      Object.values(businessState.subscription.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]
        }
      });
    }
    if (
      name === "information" &&
      informationState.subscription.service[0] !== undefined &&
      !Object.values(informationState.subscription.service).includes(newService)
    ) {
      const oldInformationPurchaseService = informationState.purchase.service;
      const oldInformationPurchaseCost = informationState.purchase.cost;
      const oldInformationSubscriptionService =
        informationState.subscription.service;
      const oldInformationSubscriptionCost = informationState.subscription.cost;
      setInformationState({
        purchase: {
          service: [...oldInformationPurchaseService, newService],
          cost: [...oldInformationPurchaseCost, newPCost]
        },
        subscription: {
          service: [...oldInformationSubscriptionService, newService],
          cost: [...oldInformationSubscriptionCost, newCost]
        }
      });
    }
    if (
      name === "information" &&
      informationState.subscription.service[0] !== undefined &&
      Object.values(informationState.subscription.service).includes(newService)
    ) {
      const removeInformationIndex = informationState.subscription.service.indexOf(
        newService
      );
      const reducedInformationSubscriptionService = informationState.subscription.service.filter(
        (s, i) => i !== removeInformationIndex
      );
      const reducedInformationSubscriptionCost = informationState.subscription.cost.filter(
        (s, i) => i !== removeInformationIndex
      );
      const reducedInformationPurchaseService = informationState.purchase.service.filter(
        (s, i) => i !== removeInformationIndex
      );
      const reducedInformationPurchaseCost = informationState.purchase.cost.filter(
        (s, i) => i !== removeInformationIndex
      );
      setInformationState({
        purchase: {
          service: [...reducedInformationPurchaseService],
          cost: [...reducedInformationPurchaseCost]
        },
        subscription: {
          service: [...reducedInformationSubscriptionService],
          cost: [...reducedInformationSubscriptionCost]
        }
      });
    }
    if (
      name === "information" &&
      informationState.subscription.service[0] === undefined
    ) {
      setInformationState({
        purchase: {
          service: [newService],
          cost: [newPCost]
        },
        subscription: {
          service: [newService],
          cost: [newCost]
        }
      });
    }
    if (
      name === "ecommerce" &&
      ecommerceState.subscription.service[0] !== undefined &&
      !Object.values(ecommerceState.subscription.service).includes(newService)
    ) {
      const oldEcommercePurchaseService = ecommerceState.purchase.service;
      const oldEcommercePurchaseCost = ecommerceState.purchase.cost;
      const oldEcommerceSubscriptionService =
        ecommerceState.subscription.service;
      const oldEcommerceSubscriptionCost = ecommerceState.subscription.cost;
      setEcommerceState({
        purchase: {
          service: [...oldEcommercePurchaseService, newService],
          cost: [...oldEcommercePurchaseCost, newPCost]
        },
        subscription: {
          service: [...oldEcommerceSubscriptionService, newService],
          cost: [...oldEcommerceSubscriptionCost, newCost]
        }
      });
    }
    if (
      name === "ecommerce" &&
      ecommerceState.subscription.service[0] !== undefined &&
      Object.values(ecommerceState.subscription.service).includes(newService)
    ) {
      const removeEcommerceIndex = ecommerceState.subscription.service.indexOf(
        newService
      );
      const reducedEcommerceSubscriptionService = ecommerceState.subscription.service.filter(
        (s, i) => i !== removeEcommerceIndex
      );
      const reducedEcommerceSubscriptionCost = ecommerceState.subscription.cost.filter(
        (s, i) => i !== removeEcommerceIndex
      );
      const reducedEcommercePurchaseService = ecommerceState.purchase.service.filter(
        (s, i) => i !== removeEcommerceIndex
      );
      const reducedEcommercePurchaseCost = ecommerceState.purchase.cost.filter(
        (s, i) => i !== removeEcommerceIndex
      );
      setEcommerceState({
        purchase: {
          service: [...reducedEcommercePurchaseService],
          cost: [...reducedEcommercePurchaseCost]
        },
        subscription: {
          service: [...reducedEcommerceSubscriptionService],
          cost: [...reducedEcommerceSubscriptionCost]
        }
      });
    }
    if (
      name === "ecommerce" &&
      ecommerceState.subscription.service[0] === undefined
    ) {
      setEcommerceState({
        purchase: {
          service: [newService],
          cost: [newPCost]
        },
        subscription: {
          service: [newService],
          cost: [newCost]
        }
      });
    }
  };

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

  const pricingCarouselOptions = {
    type: "slider",
    perView: 3,
    gap: 30,
    bound: true,
    breakpoints: {
      1199: {
        perView: 2,
        type: "carousel",
        peek: {
          before: 100,
          after: 100
        }
      },
      990: {
        type: "carousel",
        perView: 1,
        peek: {
          before: 160,
          after: 160
        }
      },
      767: {
        type: "carousel",
        perView: 1,
        peek: {
          before: 80,
          after: 80
        }
      },
      575: {
        type: "carousel",
        perView: 1,
        gap: 15,
        peek: {
          before: 20,
          after: 20
        }
      }
    }
  };

  return (
    <Box {...sectionWrapper} id="pricing_section">
      <Container>
        <Box {...secTitleWrapper}>
          <Text {...secText} content="PRICING PLAN" />
          <Heading
            {...secHeading}
            content="Customize your website according to your needs"
          />
          <PricingButtonWrapper>
            <Button
              title="Monthly Subscription Pricing"
              className={activeStatus ? "active-item" : ""}
              onClick={() =>
                setState({ data: MONTHLY_PRICING_TABLE, active: true })
              }
            />
            <Button
              title="One-Time Purchase Pricing"
              className={activeStatus === false ? "active-item" : ""}
              onClick={() =>
                setState({ data: YEARLY_PRICING_TABLE, active: false })
              }
            />
            <Link href="#">
              <a>+ Custom Plan</a>
            </Link>
          </PricingButtonWrapper>
        </Box>
        <PricingTableWrapper>
          <GlideCarousel
            carouselSelector="pricing-carousel"
            options={pricingCarouselOptions}
            controls={false}
          >
            <>
              {data.map((pricingTable, index) => (
                <GlideSlide key={`pricing-table-${index}`}>
                  <PricingTable
                    freePlan={pricingTable.freePlan}
                    className="pricing_table"
                  >
                    <PricingHead>
                      <Heading content={pricingTable.name} {...nameStyle} />
                      <Text
                        content={pricingTable.description}
                        {...descriptionStyle}
                      />
                    </PricingHead>
                    <PricingPrice>
                      {pricingTable.name === "Informational Website" &&
                      pricingTable.type === "subscription" ? (
                        <Text
                          content={`$${informationTotal.subscription}`}
                          {...priceStyle}
                        />
                      ) : pricingTable.name === "Informational Website" &&
                        pricingTable.type === "purchase" ? (
                        <Text
                          content={`$${informationTotal.purchase}`}
                          {...priceStyle}
                        />
                      ) : pricingTable.name === "Business Website" &&
                        pricingTable.type === "subscription" ? (
                        <Text
                          content={`$${businessTotal.subscription}`}
                          {...priceStyle}
                        />
                      ) : pricingTable.name === "Business Website" &&
                        pricingTable.type === "purchase" ? (
                        <Text
                          content={`$${businessTotal.purchase}`}
                          {...priceStyle}
                        />
                      ) : pricingTable.category === "ecommerce" &&
                        pricingTable.type === "subscription" ? (
                        <Text
                          content={`$${ecommerceTotal.subscription}`}
                          {...priceStyle}
                        />
                      ) : pricingTable.category === "ecommerce" &&
                        pricingTable.type === "purchase" ? (
                        <Text
                          content={`$${ecommerceTotal.purchase}`}
                          {...priceStyle}
                        />
                      ) : (
                        <Text content="error" {...priceStyle} />
                      )}
                      <Text
                        content={pricingTable.priceLabel}
                        {...priceLabelStyle}
                      />
                    </PricingPrice>
                    <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);
                            }}
                            // onChange={e => {
                            //   toggleHandler;
                            //   handleChecking(e);
                            // }}
                          />
                          {/* <Text content={item.content} {...listContentStyle} /> */}
                          {pricingTable.type === "subscription" ? (
                            <Text
                              content={`$${item.cost}`}
                              {...listContentStyle}
                            />
                          ) : (
                            <Text
                              content={`$${item.pcost}`}
                              {...listContentStyle}
                            />
                          )}
                        </ListItem>
                      ))}
                    </PricingList>
                    <PricingButton>
                      <Link href={pricingTable.url}>
                        <a>
                          <Button
                            title={pricingTable.buttonLabel}
                            {...buttonFillStyle}
                          />
                        </a>
                      </Link>
                      {pricingTable.trialButtonLabel ? (
                        <Link href={pricingTable.trialURL || "#"}>
                          <a className="trial_button">
                            {pricingTable.trialButtonLabel}
                          </a>
                        </Link>
                      ) : (
                        ""
                      )}
                    </PricingButton>
                  </PricingTable>
                </GlideSlide>
              ))}
            </>
          </GlideCarousel>
        </PricingTableWrapper>
      </Container>
    </Box>
  );
};

export default PricingSection;

数据示例:

 {
    name: "Informational Website",
    category: "information",
    type: "subscription",
    description:
      " Beautiful landing page for small businesses or personal portfolios",
    price: "$0",
    priceLabel: "Per month",
    buttonLabel: "Start for free",
    url: "#",
    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]
      }
    ]
  },

0 个答案:

没有答案