添加事件处理程序并更新状态

已完成

将状态存储在应用程序 (App) 的核心组件中时,可以读取所有重要属性的当前值。 无需与每个组件进行交互。 我们还可以集中事件,确保只在一个位置修改数据。

方案

我们想让应用程序的用户在准备好某项原料时,可以在原料列表中点击它。 我们会将各项原料标记为 prepared 状态。 此设置将反映到整个应用程序中。 如果值发生更改,组件将根据需要检测更新并重新评估。

为单击事件添加方法

  1. 打开 App.jsx 文件。

  2. 创建名为 ingredientClick 的事件侦听器。 将其添加到显示 TODO: Create ingredientClick event listener 的注释下。

    function ingredientClick(index) {
        const updatedRecipe = { ... recipe };
        updatedRecipe.ingredients[index].prepared = !updatedRecipe.ingredients[index].prepared;
        setRecipe(updatedRecipe);
    }
    

    逻辑是先使用扩展运算符创建 recipe 的副本。 然后,使用 index 检索更新的 ingredient。 我们将反转 prepared 的值。 最后,使用 setRecipe 替换状态中的 recipe 对象。

  3. 添加 IngredientList,这是显示食谱原料的组件。 为此,请将以下代码添加显示 TODO: Pass ingredients and event listener to IngredientList 的注释之后。

    <IngredientList ingredients={recipe.ingredients} onClick={ ingredientClick } />
    

    注意,我们可以像传递其他任何属性一样将 ingredientClick 函数传递给组件。

更新 IngredientList 以使用事件侦听器

在 React 中,属性(或 props)可以是任何 JavaScript 类型,包括函数。 因此我们可以将事件处理程序设置为属性。此设置可让我们集中处理事件。

更新 IngredientList 以使用我们之前创建的 ingredientClick 函数:

  1. 打开 IngredientList.jsx 文件。 请注意现有的组件。 我们将使用此组件来显示如何使用事件。

  2. TODO: Add onClick event 注释下面添加以下 JSX。

    onClick={ () => props.onClick(index) }
    

    注意,我们可以将参数传递到属性 onClick 函数。

    备注

    我们在组件的 props 上使用 onClick 这个名称并没有什么特殊的原因。 这只是我们选择的名称。 它是之前从 App.jsx 文件传入的。

测试页面

  1. 保存所有文件。
  2. 返回到浏览器并刷新页面。 如果你选择了原料,则 line-through 状态应该会发生更改。 它发生更改是因为 prepared 属性正在更新。