React组件未按预期更新状态

时间:2017-01-28 04:35:39

标签: reactjs

我正在构建一个简单的食谱列表应用程序并遇到问题。我可能误解了React如何呈现的基本信息。

以下是我codepen的部分代码 (向下滚动到我解释代码和问题的地方)

  save(action, item){  //this is the save method of my App component
    if (action == 'edit'){ // EDIT
      ...
    } else if (action == 'delete'){ // DELETE
      let newRecipes = this.state.recipes.filter( function(recipe){ return recipe.key != item.key } ) //this correctly removes the item I want to delete
      this.state.recipes = newRecipes; //making extra sure the state is updated
      this.setState({ recipes: newRecipes }); //shouldn't this make App render?
      this.forceUpdate(); //cmon App, please re-render
      console.log('newRecipes', newRecipes);
      console.log('main state', this.state); //the state was updated as expected, but App does not show what the state contains
    }

稍后,在App的render()

<ul className="well list-group">
          {
            this.state.recipes.map( (recipe)=>{  //i expect the recipe items generated to reflect App's new state, but they dont :(
              return(
                <Recipe
                  save={this.save}
                  original={recipe}
                  id={recipe.key} 
                  title={recipe.title} 
                  ingredients={recipe.ingredients} 
                  instructions={recipe.instructions} 
                />
              )
            } )
          }
        </ul>

我的应用是这样的:

我在顶部有一个应用程序组件,它呈现所有其他组件,其状态应包含有关应用程序整体的所有数据。

state.recipes是一个包含配方对象的数组。它们作为属性传递给App渲染方法中的Recipe组件。 (<Recipe title=... />

<Recipe />组件具有编辑和删除配方的方法和按钮。编辑或删除配方时,更改由App中的save()方法处理,该方法也作为道具传递给<Recipe />

根据我的理解,这是所有标准的React用法。

这一切似乎都按预期工作。当我编辑或删除配方时,更改会在应用程序状态中正确反映。

问题

删除配方时会发生意外行为。即使从App状态中删除了正确的配方,该更改也不会反映在呈现的HTML中。相反,无论App.state.recipes数组中的最后一个配方被删除,我都会盯着状态的控制台日志并呈现显示不同内容的HTML。

我尝试了什么:

我希望使用setState({ recipes: newRecipes})将App状态更新为新更新的食谱列表并在屏幕上显示。但这似乎不起作用。我甚至使用了.forceUpdate()但是没有用。

我在Recipe的构造函数中添加了一些控制台日志记录,并了解到它只在开始时运行一次。当App状态中的配方数组发生变化时,它不再像我期望的那样再次运行。

1 个答案:

答案 0 :(得分:0)

你错过了在Recipe元素上放置一个关键属性,因为React不知道哪些项目正在改变以及如何对该更改作出反应。如果你只是把关键属性一切都按预期工作。

    .brand-logo {
  margin: 0 10px 0 10px;
}

.YellowtailLogo {
    font-family: 'Yellowtail', cursive;
}
.brand-logo img{
    height: 28px;
    position: relative;
    margin-right: 10px;
    top: 3px;
}

.h1Landing {
    font-family: 'Yellowtail', cursive;
    color: #ee6e73;
}

.msg_page_container {
    height: 100%;
    position: fixed;
    width: 100%;
    overflow: hidden;
    left: 0px;
    padding: 0 10% 0 10%;

    .collection {
      overflow: scroll;
      height: 40%;
    }

    .msg_input_div{

    }
}

请记住为从迭代中创建的所有组件添加键属性。

看看你在这里工作的例子 http://codepen.io/damianfabian/pen/egeevR