簡體   English   中英

如何在依賴於另一個 state 的 useState 中設置初始 state

[英]How to set initial state in useState dependent on another state

有來自 API 的產品(在 state 'productsList' 中),我正在構建一個輸入范圍 slider,它將初始值設置為昂貴價格的值。

所以,我只想使用這一行:

const [maxPriceInSlider, setMaxPriceInSlider] = useState(maxPricedProductPrice);

maxPricedProductPrice 來自productsList state 中的最高值。

但它不工作。

任何幫助表示贊賞。

該組件的完整代碼為:

import React from "react";
import { useEffect, useState } from "react";

import axios from "axios";
import { ColorRing as Loader } from "react-loader-spinner";
import HeroGeneral from "../components/UI/HeroGeneral";
import BidItem from "../components/General/BidItem";
import "./bidslist.css";

const BidsList = () => {
  const [loading, setLoading] = useState(false);
  const [productsList, setProductsList] = useState([]);

  // get maximum priced product price
  const maxPricedProductPrice = Math.max(...productsList.map((prod) => prod.basePrice));

  const [minPriceInSlider, setMinPriceInSlider] = useState(0);

  // --------------------------------------------------------------------------------------

  // --------------- I WANT the maxPricedProductPrice to be set as initial state of maxPriceInSlider like this:
  //    const [maxPriceInSlider, setMaxPriceInSlider] = useState(maxPricedProductPrice);
  // But it is not working
  // productsList is coming from API
  const [maxPriceInSlider, setMaxPriceInSlider] = useState(0);

  const onMinPriceSliderChangeHandler = (e) => {
    setMinPriceInSlider(e.target.value);
  };
  const onMaxPriceSliderChangeHandler = (e) => {
    setMaxPriceInSlider(e.target.value);
  };

  // fetch all the prodcuts AFTER 1st page render
  useEffect(() => {
    // scroll to top on mount
    window.scrollTo(0, 0);
    setLoading(true);
    axios
      .get("http://localhost:5000/api/v1/products")
      .then((data) => {
        setProductsList(data.data.data.products);
        setLoading(false);
      })
      .catch((err) => {
        setLoading(false);
      });
  }, []);

  return (
    <div>
      <HeroGeneral />
      <div className="bidlist_page_content">
        <aside className="filter">
          <h2>Filter by</h2>
          <div className="filterby_cat">
            <h3>Category: </h3>
            <select name="c" id="">
              <option value="Electronics">Electronics</option>
              <option value="Others">Others</option>
            </select>
          </div>
          <div className="filterby_price">
            <h3>
              Start price:{" "}
              <input
                type="range"
                name="minPriceInSlider"
                value={minPriceInSlider}
                min="0"
                max={maxPricedProductPrice}
                onChange={onMinPriceSliderChangeHandler}
              />
              {minPriceInSlider}
            </h3>
            <h3>
              End price:{" "}
              <input
                type="range"
                name="maxPriceInSlider"
                value={maxPriceInSlider}
                min="0"
                max={maxPricedProductPrice}
                onChange={onMaxPriceSliderChangeHandler}
              />
              {maxPriceInSlider}
            </h3>
          </div>
        </aside>
        <div>
          <div className="divlist_grid_main">
            {loading && (
              <Loader
                visible={true}
                height="100"
                width="100"
                ariaLabel="blocks-loading"
                wrapperStyle={{}}
                wrapperClass="blocks-wrapper"
                colors={["#212529"]}
              />
            )}
            {!loading && productsList.length === 0 && "No products found!"}
            {productsList.map((prod) => (
              <BidItem
                key={prod._id}
                description={prod.description}
                category={prod.category}
                name={prod.name}
                closesAt={prod.closesAt}
                imgURL={prod.imageURL}
                prodId={prod._id}
                bPrice={prod.basePrice}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

export default BidsList;

像下面這樣更新maxPriceInSlider中的 maxPriceInSlider 有什么問題嗎?

useEffect(() => {
    // scroll to top on mount
    window.scrollTo(0, 0);
    setLoading(true);
    axios
      .get("http://localhost:5000/api/v1/products")
      .then((data) => {
        setProductsList(data.data.data.products);
        const tempProducts = data.data.data.products;
        const maxPricedProductPrice = Math.max(...tempProducts.map((prod) => prod.basePrice));
        // update the max price here
        setMaxPriceInSlider(maxPricedProductPrice);
        setLoading(false);
      })
      .catch((err) => {
        setLoading(false);
      });
  }, []);

如果這對您不起作用,您可以隱藏范圍輸入,直到 API 呼叫結束,一旦您獲得最高價格,然后在屏幕上顯示它。

您可以嘗試不同的方法。 從 API 檢索數據並設置 productsList 后,還同時設置了 maxPrieceInSlider,如下所示:

axios
      .get("http://localhost:5000/api/v1/products")
      .then((data) => {
        const maxPricedProductPrice = Math.max(...productsList.map((prod) => prod.basePrice));
        setProductsList(data.data.data.products);
        setMaxPriceInSlider(maxPricedProductPrice);
        setLoading(false);
      })
      .catch((err) => {
        setLoading(false);
      });

這效率更高,因為如果您像以前一樣在代碼的開頭繼續執行最高價格操作,它會阻礙您的應用程序,因為每次反應都會重新呈現您的組件,此操作將不必要地一次又一次地執行。

讓我如果它有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM