为地图函数内的每个项目调用 api 时重新渲染次数过多

问题描述 投票:0回答:1

当我映射 order_item 数组时,它会检查条件,并在 else 块中通过 fetchData 函数进行 api 调用,该函数在订单项的每个项目上运行。从技术上讲,它应该在地图项完成后停止,但它只是继续无限循环运行。

  item.order_item.map((item2, index) => {
    if (!item2.order_meal_deliveries.length > 0) {
      return (
        <div className="col-12 card card-md mb-4" key={index}>
          <div className="col-auto">
            <div className="row">
              <div className="col-lg">
                <div className="col-12 p-4">
                  <div className="col-12">
                    <div className="row align-items-center">
                      <div className="col">
                        <div className="tag mb-2">
                          {item2.plan_type === 1 ? "Wellness" : "Individual"}
                        </div>
                      </div>
                      <div className="col-auto">
                        <p className="mb-0 text-grey">
                          <span className="fw-bold">Order ID:</span> MUSF00
                          {item.id}
                        </p>
                      </div>
                    </div>
                  </div>
                  <h5 className="fw-semibold ">
                    {item2.item_details.product_title}&nbsp;&nbsp;
                    <span className="fw-regular text-grey"></span>&nbsp;&nbsp;
                  </h5>
                  <p className="text-grey mb-4">
                    Durations: {item2.subscription_days} day
                  </p>
                  <h6 className="mb-1">Plan duration</h6>
                  <p className="text-grey">
                    Not Started of {item2.subscription_days} Days
                  </p>
                  <div className="progress">
                    <div
                      className="progress-bar"
                      role="progressbar"
                      aria-valuemax="100"
                      style={{ width: "0%" }}
                    ></div>
                  </div>
                </div>
              </div>
              <div className="col-lg-5 border-start d-flex align-items-center">
                <div className="col-12 p-4 text-center  ">
                  <div className="col-12 form-group ">
                    <h6 className="mb-1 fw-medium text-start">
                      Start your plan
                    </h6>
                    <DatePicker
                      selected={startDate}
                      onChange={(date) => {
                        setStartDate(date);
                      }}
                      minDate={minDate}
                      className="form-control col-12"
                      dateFormat={"dd/MM/yyyy"}
                    />
                  </div>
                  {/* <div className="col-12 form-group">
                                                                                <h6 className="mb-1 fw-medium">End date</h6>
                                                                                <input type="text" className="form-control" placeholder="Select date" />
                                                                            </div> */}
                  <button
                    className="btn btn-primary"
                    onClick={() =>
                      createMealDelivery(item.id, item2.id, item2.plan_type)
                    }
                  >
                    Start meal plan
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    } else {
      fetchData(item.id, item2.id);

      return (
        <div className="col-12 card card-md mb-4" key={index}>
          <div className="col-auto">
            <div className="row">
              <div className="col-lg">
                <div className="col-12 p-4">
                  <div className="col-12">
                    <div className="row align-items-center">
                      <div className="col">
                        <div className="tag mb-2">
                          {item2.plan_type === 1 ? "Wellness" : "Individual"}
                        </div>
                      </div>
                      <div className="col-auto">
                        <p className="mb-0 text-grey">
                          <span className="fw-bold">Order ID:</span> MUSF00
                          {item.id}
                        </p>
                      </div>
                    </div>
                  </div>
                  <h5 className="fw-semibold ">
                    {item2.item_details.product_title}&nbsp;&nbsp;
                    <span className="fw-regular text-grey"></span>&nbsp;&nbsp;
                  </h5>
                  <p className="text-grey mb-4">
                    Durations: {item2.subscription_days} day
                  </p>
                  <h6 className="mb-1">Plan duration</h6>
                  <p className="text-grey">
                    Not Started of {item2.subscription_days} Days
                  </p>
                  <div className="progress">
                    <div
                      className="progress-bar"
                      role="progressbar"
                      aria-valuemax="100"
                      style={{ width: setProgressBarValue() }}
                    ></div>
                  </div>
                  <div className="col-12 pt-4 mt-4 border-top">
                    <div className="row justify-content-between">
                      <div className="col-auto">
                        <button
                          className="btn btn-outline-primary"
                          onClick={() => handleViewMeal(item2.id, item.id)}
                        >
                          View plan
                        </button>
                      </div>
                      <div className="col-auto">
                        <button
                          className="btn btn-primary"
                          onClick={() => handleRenewPlan(item2)}
                        >
                          Renew plan
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    }
  }),
);
const fetchData = (orderId, itemId) => {
  api
    .ordersDelivery(orderId, itemId)

    .then((res) => {
      //    console.log(res?.data?.response?.pending_delivery_count)
      setPendingDeliveries(res?.data?.response?.pending_delivery_count);
      //    console.log(res?.data?.response?.total_delivery_count)
      setTotalDeliveries(res?.data?.response?.total_delivery_count);
    })

    .catch((err) => {
      console.log(err);
    });
};

我知道这种行为的原因,地图函数中的状态设置导致它重新渲染组件。

每个项目都应该有自己的待交付和总交付值,该值取自API响应,我如何实现这一点

reactjs axios logic jsx
1个回答
0
投票

我认为如果

item2
没有
order_meal_deliveries
,你想要做的是调用你的Api? 我认为最简单的方法是为地图功能创建一个新组件。

新的 Item 组件

    export const Item = (item2, itemId) => {
  const [pendingDeliveriesCount, setPendingDeliveriesCount] = useState();
  const [totalDeliveriesCount, setTotalDeliveriesCount] = useState();

  useEffect(() => {
   if(item2.order_meal_deliveries.length === 0){
    api.ordersDelivery(orderId, item2.id)
    .then(res => {
    //    console.log(res?.data?.response?.pending_delivery_count)
    setPendingDeliveriesCount(res?.data?.response?.pending_delivery_count);
    //    console.log(res?.data?.response?.total_delivery_count)
    setTotalDeliveriesCount(res?.data?.response?.total_delivery_count);
    })

    .catch(err => {
        console.log(err);
    });
   }
  }, [item2, itemId]);

  return (
    <div className="col-12 card card-md mb-4" key={index}>
      <div className="col-auto">
        <div className="row">
          <div className="col-lg">
            <div className="col-12 p-4">
              <div className="col-12">
                <div className="row align-items-center">
                  <div className="col">
                    <div className="tag mb-2">
                      {item2.plan_type === 1 ? "Wellness" : "Individual"}
                    </div>
                  </div>
                  <div className="col-auto">
                    <p className="mb-0 text-grey">
                      <span className="fw-bold">Order ID:</span> MUSF00{item.id}
                    </p>
                  </div>
                </div>
              </div>
              <h5 className="fw-semibold ">
                {item2.item_details.product_title}&nbsp;&nbsp;
                <span className="fw-regular text-grey"></span>&nbsp;&nbsp;
              </h5>
              <p className="text-grey mb-4">
                Durations: {item2.subscription_days} day
              </p>
              <h6 className="mb-1">Plan duration</h6>
              <p className="text-grey">
                Not Started of {item2.subscription_days} Days
              </p>
              <div className="progress">
                <div
                  className="progress-bar"
                  role="progressbar"
                  aria-valuemax="100"
                  style={{ width: "0%" }}
                ></div>
              </div>
            </div>
          </div>
          {!item2.order_meal_deliveries.length > 0 ? (
            <div className="col-lg-5 border-start d-flex align-items-center">
              <div className="col-12 p-4 text-center  ">
                <div className="col-12 form-group ">
                  <h6 className="mb-1 fw-medium text-start">Start your plan</h6>
                  <DatePicker
                    selected={startDate}
                    onChange={(date) => {
                      setStartDate(date);
                    }}
                    minDate={minDate}
                    className="form-control col-12"
                    dateFormat={"dd/MM/yyyy"}
                  />
                </div>
                {/* <div className="col-12 form-group">
                      <h6 className="mb-1 fw-medium">End date</h6>
                      <input type="text" className="form-control" placeholder="Select date" />
                  </div> */}
                <button
                  className="btn btn-primary"
                  onClick={() =>
                    createMealDelivery(item.id, item2.id, item2.plan_type)
                  }
                >
                  Start meal plan
                </button>
              </div>
            </div>
          ) : (
            <div className="col-12 pt-4 mt-4 border-top">
              <div className="row justify-content-between">
                <div className="col-auto">
                  <button
                    className="btn btn-outline-primary"
                    onClick={() => handleViewMeal(item2.id, item.id)}
                  >
                    View plan
                  </button>
                </div>
                <div className="col-auto">
                  <button
                    className="btn btn-primary"
                    onClick={() => handleRenewPlan(item2)}
                  >
                    Renew plan
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

地图功能改版

  mealPlans.map((item, mealIndex) =>
  item.order_item.map((item2, index) => {        
      return <Item item2={item2} itemId={itemId}></Item>;        
  })
);
© www.soinside.com 2019 - 2024. All rights reserved.