【问题标题】:Item list fetched with useEffect hook renders only after it is filtered with useEffect使用 useEffect 挂钩获取的项目列表仅在使用 useEffect 过滤后才会呈现
【发布时间】:2020-04-16 04:50:37
【问题描述】:

我的问题是我尝试使用 useEffect 和 useState 挂钩在第一次渲染时显示数据(项目列表),并且在渲染后我想过滤这些映射的项目。

在我进入项目页面的那一刻,我在页面上呈现了零个项目。并且只有在我过滤它们之后才会呈现它们(通过搜索过滤器或从选择下拉列表中选择所需的颜色)。

下面是我的代码:

...
  var [searchTerm, setSearchTerm] = useState<any>("");
  var [searchResults, setSearchResults] = useState<any>([]);
  const handleInput = (e: any) => {
    console.log(e.target.value);
    setSearchTerm(e.target.value);
  };
  var [pickedColor, setPickedColor] = useState<any>("");
  var [colorPickResults, setColorPickResults] = useState<any>([]);
  const handleColorChange = (e: any) => {
    console.log(e.target.value);
    setPickedColor(e.target.value);
  };
  var [items, setItems] = useState<any>([]);
  useEffect(() => {
    var message: string = "";
    var fetchItems = () => {
      axios
        .get("/api/products")
        .then((res: any) => {
          console.log("res :", res);
          setItems(res.data.data[0].products);
          console.log("res.data.data[0].products :", res.data.data[0].products);
          if (res.status === 200) {
            message = "Products successfuly fetched.";
            console.log(message);
          } else {
            message = "Something went wrong. Please try again later.";
            console.log(message);
          }
        })
        .catch((err: any) => console.log(err));
    };
    fetchItems();
    const resultsFromSearch = items.filter((item: any) =>
      item.title.toLowerCase().includes(searchTerm)
    );
    setSearchResults(resultsFromSearch);
    const resultsFromPickedColor = resultsFromSearch.filter((item: any) =>
      item.color.toLowerCase().includes(pickedColor)
    );
    setColorPickResults(resultsFromPickedColor);
  }, [searchTerm, pickedColor]);
  var filteredItems = colorPickResults;
  var itemList = filteredItems.map((item: any) => {
    return (
      <div key={item.id} style={{ width: "370px", padding: "1rem" }}>
...

我在控制台中收到成功消息,并且如上所述成功获取项目。

我尝试过的: 1.将“items”添加到:[searchTerm,pickColor,items] 数组,但随后 useEffect 在获取项目时创建无限循环,并且(可能)在每次获取时重新渲染组件。

我可以更改哪些内容来获得帖子开头提到的所需功能? 我应该添加一些其他的钩子,比如 useContext、useMemo 吗?或者也许我可以以某种方式将提取与过滤分开?

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    调用异步函数并尝试访问稍后将返回的数据将永远无法按预期工作

    fetchItems();
    const resultsFromSearch = items.filter((item: any) =>
      item.title.toLowerCase().includes(searchTerm)
    );
    

    您应该将该代码添加到 .then 内的 fetchItems 或者可能有单独的 useEffect

    useEffect(() => {
    const resultsFromSearch = items.filter((item: any) =>
          item.title.toLowerCase().includes(searchTerm)
        );
    setSearchResults(resultsFromSearch);
    }, [items])
    

    对我来说,第二个选项更具声明性和灵活性,但这取决于您

    【讨论】:

    • 感谢您的回答,我会将其标记为已接受,但还有另一件事需要更改。您的第二个选项有效,用于在第一次渲染时获取和显示所有数据,第一个选项没有。另一件事是我必须像这样更改数组:[items,searchTerm,pickColor]。而不是这样:[items, searchResults, colorPickResults]
    • 对不起,不要关注。您在哪里(错误地)在代码中使用了[items, searchResults, colorPickResults]
    • 抱歉误导性评论,在代码中,正确的值是:[items, searchTerm,pickColor]。只是当我尝试使用您提供的信息修复代码时,我还通过将上面的数组替换为:[items, searchResults, colorPickResults] 给我带来了另一个问题。所以最后放在那里的正确数组是:[items,searchTerm,pickColor],并创建两个 useEffect,其中一个用于在末尾使用空数组 [] 进行提取。
    猜你喜欢
    • 2021-02-13
    • 2020-02-15
    • 2021-07-19
    • 1970-01-01
    • 2022-01-16
    • 2022-01-17
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    相关资源
    最近更新 更多