嵌套列表
import { recipes } from './data.js';
export default function RecipeList() {
return (
<div>
<h1>菜谱</h1>
{recipes.map(recipe =>
<div key={recipe.id}>
<h2>{recipe.name}</h2>
<ul>
{recipe.ingredients.map(ingredient =>
<li key={ingredient}>
{ingredient}
</li>
)}
</ul>
</div>
)}
</div>
);
}
recipes 数组中每一项都拥有一个 id,所以外层的循环可以直接拿它作为 key。不过,在循环遍历原料的时候就没有现成的 id 可以用了。但是,合理推测一下,一份菜谱里不会罗列多次同一种原料,所以其实原料的名字就适合作为 key。此外,你也可以自行修改原本的数据人为增加一项 id,或是使用索引作为 key(需要注意的是,这么做会使你无法正常地对原料进行排序)。
讲其提取为组件
import { recipes } from './data.js';
function Recipe({ id, name, ingredients }) {
return (
<div>
<h2>{name}</h2>
<ul>
{ingredients.map(ingredient =>
<li key={ingredient}>
{ingredient}
</li>
)}
</ul>
</div>
);
}
export default function RecipeList() {
return (
<div>
<h1>菜谱</h1>
{recipes.map(recipe =>
<Recipe {...recipe} key={recipe.id} />
)}
</div>
);
}
这里的 <Recipe {...recipe} key={recipe.id} /> 是一种简写方式,它表示“把 recipe 对象里的每个属性都作为 props 传给 Recipe 组件”。这和直接写明每一个 prop 是等价的:<Recipe id={recipe.id} name={recipe.name} ingredients={recipe.ingredients} key={recipe.id} />。
注意这里的 key 是写在 <Recipe> 组件本身上的,不要写在 Recipe 内部返回的 <div> 上。 这是因为 key 只有在就近的数组上下文中才有意义。之前的写法里,我们生成了一个 <div> 的数组所以其中的每一项需要一个 key,但是现在的写法里,生成的实际上是 <Recipe> 的数组。换句话说,在提取组件的时候,key 应该写在复制粘贴的 JSX 的外层组件上。