【问题标题】:trouble updating state in object with componentDidUpdate无法使用 componentDidUpdate 更新对象中的状态
【发布时间】:2020-04-13 11:07:34
【问题描述】:

所以我正在制作一个食谱应用程序并完成了大部分工作。我现在正在寻找集成高级搜索功能,以便用户可以在点击搜索按钮之前过滤他们想要查看的内容。所以现在,与这个问题相关的状态部分看起来像这样

advancedSearchParameters: [

            ]

在输入一个术语(斯里兰卡)并点击搜索组件中的搜索按钮时,状态中的 advancedSearchParameters 将更新为类似这样的内容

{
                        balanced: false,
                        highProtein: false,
                        highFibre: false,
                        lowFat: false,
                        lowCarb: false,
                        lowSodium: false,
                        vegan: false,
                        vegetarian: false,
                        dairyFree: false,
                        glutenFree: false,
                        lowSugar: false,
                        peanutFree: false,
                        resultNum: 20,
                        searchTerm: ''
                    }

这将提示组件更新

async componentDidUpdate(prevProps, prevState) {
            if (
                prevState.advancedSearchParameters !== this.advancedSearchParameters &&
                this.state.advancedSearchParameters.searchTerm !== ''
            ) {
                let response = await axios.get(
                    `https://api.edamam.com/search?q=${this.state.advancedSearchParameters
                        .searchTerm}&app_id=cf7e1&app_key=946d6fb34df02a86bd47b89433&to=20`
                );
                let data = response.data.hits.map((data) => ({
                    name: data.recipe.label,
                    src: data.recipe.image,
                    source: data.recipe.source,
                    url: data.recipe.url,
                    healthLabels: data.recipe.healthLabels,
                    dietLabels: data.recipe.dietLabels,
                    calories: data.recipe.calories,
                    totalWeight: data.recipe.totalWeight,
                    totalTime: data.recipe.totalTime,
                    totalNutrients: data.recipe.totalNutrients,
                    ingredients: data.recipe.ingredients
                }));
                this.setState({ recipeResults: data });
            }
        }

当我这样做时出现的问题是 API 调用似乎被发送了多次,提示 API 阻止我的请求至少一分钟。谁能看到我哪里出错了?

【问题讨论】:

  • 不要使用componentDidUpdate来获取异步请求,为什么不使用点击处理程序,我的意思是你传递给你搜索按钮的onClick prop的函数?
  • 因为这是对外部 API 的调用,据我所知,应该在 componentDidUpdate @rzwnahmd 中调用更改我的状态和呈现新组件的 Api 调用

标签: javascript reactjs api


【解决方案1】:

componentDidUpdate 通常被调用来处理 props 的变化,但你没有这样做。您使用 componentDidUpdate 来处理状态的更改,然后更新将重新触发它的内部状态。您应该将该代码移出 componenDidUpdate 并将其放在您更新 advancedSearchParameters 状态的位置,可能在 input.onChange 回调中。

还有一件事,当您进行实时搜索时,您在每次击键时都会调用您的 api。有两种方法可以解决这个问题。

  1. 使用 axios 取消令牌,因此您可以在发送新请求之前取消现有的 axios 请求

  2. 消除您的 axios 调用,这是一个 javascript 函数,在用户键入密钥后会等待一小段延迟,然后再发送请求

【讨论】:

  • 对不起,我不明白,componentDidUpdate是在状态改变时触发的。当 componentDidUpdate 被触发时,API 调用被发送出去。此外,搜索不是实时的,因为在单击 @HermitCrab 时触发了状态更改
  • 我以为你在做一个像谷歌一样的实时搜索。在你的 onClick 处理程序中,调用你的 API,你会很好。在 componentDidUpdate 中调用 setState 时必须非常小心,因为您可能会陷入无限循环。如果您从 onClick 调用您的 API,您将不会遇到此问题
【解决方案2】:

解决了!我需要做的就是制作

prevState.advancedSearchParameters !== this.advancedSearchParameters

到 prevState.advancedSearchParameters !== this.state.advancedSearchParameters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-29
    • 2019-06-06
    • 2019-02-11
    • 2020-05-22
    • 2021-02-25
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多