首页 > 解决方案 > React - 在 useEffect 内向 useState 添加新参数被延迟

问题描述

在我的一个项目上工作并遇到了一个问题。所以我在我的产品中添加了“分类”。因此,例如,您可以根据颜色、品牌、尺寸等对“连帽衫”进行排序。幸运的是,我使用的 API 接受这些值,例如:brand: <brand>base_colour: <color>.

到目前为止,我已经设法获得了 API 的键和值,但它的行为有点奇怪。

每当我对产品进行分类时,它都不会立即适用。因此,例如,如果我想将“品牌”分类为“自行车”,则什么也不会发生。但是,如果我再尝试将“颜色”排序为“黑色”。然后品牌会改变,但颜色不会改变。所以它被“延迟”了一个。

通过我对这个问题的调试,我有 80% 的把握我useEffect的就是这里的小偷。

这是一张可能有帮助的图片:

在此处输入图像描述

如您所见,键和值attribute_1046被发送到我的 API fetch js 文件,但没有添加到参数中。但是每当我更改品牌时(意思是,我有 2 个分类)。然后将其attribute_1046添加到参数中。

这是我的 API 获取代码:

  // Receiving the Key and Value when a user interacts with the "sorting" dropdowns.
  let facetValue = props.facetValue;
  let facetKey = props.facetKey;

  // Setting initial parameters
  const [params, setParams] = useState({
    store: "US",
    offset: props.offset,
    categoryId: props.categoryId,
    limit: props.limit,
    country: "US",
    sort: "freshness",
    currency: "USD",
    sizeSchema: "US",
    lang: "en-US",
  });

  useEffect(() => {
    // if FacetKey is not undefined.
    if (facetKey) {
      console.log(`${facetKey}: ${facetValue}`);
      setParams({
        [facetKey]: facetValue,
        ...params,
      });
    }
    console.log(params);

    const options = {
      method: "GET",
      url: "https://asos2.p.rapidapi.com/products/v2/list",
      params: params,
      headers: {
        "x-rapidapi-key": "",
        "x-rapidapi-host": "",
      },
    };
    axios
      .request(options)
      .then(function (response) {
        setProducts(response.data.products);
        props.items(response.data.itemCount);
        props.facets(response.data.facets);
      })
      .catch(function (error) {
        console.error(error);
      });
    // Is it my dependencies that are incorrect?
  }, [props.limit, facetKey]);

不确定是否也需要此文件,但用户在这里对产品进行排序:

  const [facets, setFacets] = useState();
  const [facetValue, setFacetValue] = useState();
  const [facetKey, setFacetKey] = useState();

        <BottomBar>
          <div className={classes.filter_grid_container}>
            {facets != null
              ? facets.map((filter) => (
                  <div className={classes.item}>
                    {filter.name != "Price Range" ? (
                      <Dropdown
                        name={filter.name}
                        values={filter.facetValues}
                        facetKey={filter.id}
                        facetValue={(facetValue) => setFacetValue(facetValue)}
                        facetItemKey={(facetKey) => setFacetKey(facetKey)}
                      />
                    ) : (
                      <DropdownPrice />
                    )}
                  </div>
                ))
              : null}
          </div>
        </BottomBar>
      </StyledApp>
      <div className={classes.grid_container}>
        <FetchAPI
          limit={limit}
          offset={offset}
          items={(itemCount) => setItemCount(itemCount)}
          categoryId={params.id}
          facets={(facets) => setFacets(facets)}
          facetValue={facetValue}
          facetKey={facetKey}
        />
      </div>

标签: javascriptreactjs

解决方案


实际上问题是返回的函数useState是异步的,您正在更新paramsuseEffect 并立即访问它以传递 axios api 的请求。

问题:-

    if (facetKey) {
      console.log(`${facetKey}: ${facetValue}`);
      setParams({
        [facetKey]: facetValue,  // updating params here
        ...params,
      });
    }
    console.log(params);

    const options = {
      method: "GET",
      url: "https://asos2.p.rapidapi.com/products/v2/list",
      params: params,  // using it here so this will always return previous value
      headers: {
        "x-rapidapi-key": "",
        "x-rapidapi-host": "",
      },
    };

解决方案:-

    let requestParam = {};
    if (facetKey) {
      requestParam = {[facetKey]: facetValue, ...params}   // create const with expected value
      setParams({...requestParam});
    }

    const options = {
      method: "GET",
      url: "https://asos2.p.rapidapi.com/products/v2/list",
      params: requestParam,   // pass new const here in options
      headers: {
        "x-rapidapi-key": "",
        "x-rapidapi-host": "",
      },
    };

推荐阅读