简体   繁体   English

使用 componentDidUpdate 在 object 中更新 state 时遇到问题

[英]trouble updating state in object with componentDidUpdate

So I am in the midst of making a recipe app and have most of it done.所以我正在制作一个食谱应用程序并完成了大部分工作。 I am now looking to integrate an advanced search function so that users can filter what they want to see before hitting the search button.我现在正在寻找集成高级搜索 function 以便用户可以在点击搜索按钮之前过滤他们想要查看的内容。 So right now, the part of the state that is relevant to this question looks like this所以现在,与这个问题相关的 state 的部分看起来像这样

advancedSearchParameters: [

            ]

On the entry of a term (sri Lankan) and click of the search button in the search component, advancedSearchParameters in the state will update to have something like this在输入一个术语(斯里兰卡)并单击搜索组件中的搜索按钮时,state 中的高级搜索参数将更新为具有类似的内容

{
                        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: ''
                    }

This will prompt the component to update with这将提示组件更新

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 });
            }
        }

The issue that occurs when i do this is that the API call appears to be sent multiple times, prompting the API to block my request for at least a minute.当我这样做时发生的问题是 API 调用似乎被多次发送,提示 API 阻止我的请求至少一分钟。 Can anyone see where I am going wrong with this?谁能看到我哪里出错了?

componentDidUpdate is usually called to handle a change in props, but you're not doing that. componentDidUpdate 通常被调用来处理道具的变化,但你没有这样做。 You use componentDidUpdate to handle the change of state and then you update the state inside which will retrigger it.您使用 componentDidUpdate 来处理 state 的更改,然后更新 state 内部,它将重新触发它。 You should move that code outside of componenDidUpdate and put it where you update your advancedSearchParameters state, probably in an input.onChange callback.您应该将该代码移到 componenDidUpdate 之外,并将其放在您更新 advancedSearchParameters state 的位置,可能在 input.onChange 回调中。

One more thing, when you do a real time search, you are calling your api at every keystroke.还有一件事,当您进行实时搜索时,每次击键时都会调用 api。 There are 2 ways to deal with that problem.有两种方法可以解决这个问题。

  1. Use axios cancel token, so you can cancel an existing axios request before sending a new one使用 axios 取消令牌,因此您可以在发送新请求之前取消现有的 axios 请求

  2. Debounce your axios call, it's a javascript function that will wait for a short delay after the user has typed a key before sending the request消除您的 axios 调用,这是一个 javascript function 将在用户在发送请求之前输入密钥后等待一小段延迟

Solved it!解决了! All i needed to do was make我需要做的就是做

prevState.advancedSearchParameters.== this.advancedSearchParameters prevState.advancedSearchParameters.== this.advancedSearchParameters

to prevState.advancedSearchParameters.== this.state.advancedSearchParameters到 prevState.advancedSearchParameters.== this.state.advancedSearchParameters

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM