【问题标题】:Defining a variable and then calling it (undefined)定义一个变量然后调用它(未定义)
【发布时间】:2019-02-19 03:48:32
【问题描述】:

我正在定义一个名为 filteredRecipes 的 const 变量,并尝试使用它来设置状态。控制台报告过滤的食谱未定义,

Uncaught ReferenceError: filteredRecipes is not defined

我看不出我做错了什么?非常感谢任何帮助。

updateRecipeList () {
    const filteredRecipes = fetch('http://www.***.co.uk/rest/recipes.json')
        .then(res => res.json())
        .then(json => {

            json.results.filter(

                function (recipe) {
                    return (
                        this.state.currentRecipe === "" || recipe.pagetitle.toLowerCase().indexOf(this.state.currentRecipe.toLowerCase()) !== -1
                    )
                }.bind(this)

            );

        });

    this.setState({
        recipes: filteredRecipes
    });
}

【问题讨论】:

    标签: javascript reactjs api filter setstate


    【解决方案1】:

    你必须在 Promise 链的末端做:

    updateRecipeList() {
        return fetch('http://www.***.co.uk/rest/recipes.json')
            .then(res => res.json())
            .then(json => {
    
                // you also missed `return` here    
                return json.results.filter(
    
                    function(recipe) {
                        return (
                            this.state.currentRecipe === "" || recipe.pagetitle.toLowerCase().indexOf(this.state.currentRecipe.toLowerCase()) !== -1
                        )
                    }.bind(this)
    
                );
    
            })
            .then(filteredRecipes => {
    
                this.setState({
                    recipes: filteredRecipes
                });
    
            });
    }
    

    我还稍微重构了您的代码,希望您不要介意。 :)

    updateRecipeList() {
        return fetch('http://www.***.co.uk/rest/recipes.json')
            .then(res => res.json())
            .then(json => {
                if (this.state.currentRecipe !== "") {
                    const currentRecipe = this.state.currentRecipe.toLowerCase()
                    const filteredRecipes = json.results.filter(recipe => (
                        recipe.pagetitle.toLowerCase().includes(currentRecipe)
                    ));
    
                    this.setState({ recipes: filteredRecipes });
                }
                else {
                    this.setState({ recipes: json.results });
                }
            });
    }
    

    【讨论】:

      【解决方案2】:

      发生这种情况是因为 fetch 是异步的,您可以通过在 then 部分中设置状态来做到这一点:

      updateRecipeList() {
      const self = this;
      fetch('http://www.***.co.uk/rest/recipes.json')
      .then(res => res.json())
      .then(json => {
          const filteredRecipes = json.results.filter(recipe =>
              self.state.currentRecipe === "" ||  recipe.pagetitle.toLowerCase().indexOf(self.state.currentRecipe.toLowerCase()) !== -1);
      
         self.setState({ recipes: filteredRecipes });
      });
      

      } 或者你可以使用 ES7 异步函数来获取结果:\

      async updateRecipeList() {
        const res = await fetch('http://www.***.co.uk/rest/recipes.json');
        const recipies = await res.json();
        const filteredRecipes = recipies.results.filter(recipe =>
           this.state.currentRecipe === "" ||recipe.pagetitle.toLowerCase().indexOf(this.state.currentRecipe.toLowerCase()) !== -1
      
         this.setState({ recipes: filteredRecipes });
      

      }

      【讨论】:

        【解决方案3】:

        原因是因为您的this.setState 在 Promise 之外,这意味着在尝试执行该代码之前我不会等待 Promise 完成。这意味着该变量将是未定义的。

        你可以像这样把它放在 Promise 中来解决这个问题:

        updateRecipeList() {
          const filteredRecipes = fetch('http://www.***.co.uk/rest/recipes.json')
            .then(res => res.json())
            .then(json => {
              json.results.filter(
                function(recipe) {
                  return (
                    this.state.currentRecipe === "" || recipe.pagetitle.toLowerCase().indexOf(this.state.currentRecipe.toLowerCase()) !== -1
                  )
                }.bind(this)
              );
              this.setState({
                recipes: filteredRecipes
              });
            });
        
        
        }
        

        【讨论】:

        • 我的意思是这可能会做 OP 想要的,但为什么 filteredRecipes 在原始版本中未定义?它应该具有fetch返回的(未解决的)Promise 对象的值
        • 此外,您也永远不会为“filteredRecipes”分配任何有意义的东西,因此在您使用它的地方仍然是未定义的。
        • 没错。在 fetch 完成之前,它基本上什么都不返回,所以变量的值将是未定义的。
        • 这没有任何意义。 fetch()立即返回一个 Promise,在它“完成”之前,你不能调用链式 then()s 否则。它是可组合异步代码的基础。
        • 您没有将.filter 的结果分配给任何变量。
        【解决方案4】:
        updateRecipeList() {
          fetch('http://www.***.co.uk/rest/recipes.json')
            .then(res => res.json())
            .then(json => {
               const result = json.results.filter(recipe => {
                   return (
                    this.state.currentRecipe === "" || recipe.pagetitle.toLowerCase().indexOf(this.state.currentRecipe.toLowerCase()) !== -1
                  );
                }
               this.setState({ recipes: result });
           );
         });
        }
        

        这是因为该线程正在异步运行,并且您需要在设置 setState 时执行 promise。

        【讨论】:

          猜你喜欢
          • 2018-07-13
          • 1970-01-01
          • 2018-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-10
          • 2020-04-20
          相关资源
          最近更新 更多