React (5) -- Lists and Keys

本文介绍了如何在React中渲染列表以及使用Keys提高性能的方法。包括基本列表组件的实现方式,Keys的作用及其最佳实践,以及如何正确地为列表项指定Keys。

原文地址:https://facebook.github.io/react/docs/lists-and-keys.html

一、Lists

1. 渲染多个组件 (Rendering Multiple Components)

构建元素集合,并使用花括号{}将它们包含在JSX中。

//Warning: Each child in an array or iterator should have a unique "key" prop.
      const numbers = [1,2,3,4,5];
      const listItems = numbers.map((number)=><li>{number}</li>);
      ReactDOM.render(
        <ul>{listItems}</ul>,
        document.getElementById("root")
      );

2. 基本列表组件 (Basic List Component)

在一个组件中渲染列表。

//Warning: Each child in an array or iterator should have a unique "key" prop.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

“key”是创建元素列表时需要包含的特殊字符串属性。

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

二、Keys

默认情况下,当对DOM节点的子代进行递归时,React只会同时遍历两个子列表,并在有差异时生成一个变异。

eg:
在最后添加一个元素时,这两个树之间的转换效果很好:

//转换前
<ul>
  <li>first</li>
  <li>second</li>
</ul>

//转换后
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

但是在开始插入元素时,性能会较差。

//转换前
<ul>
  <li>first</li>
  <li>second</li>
</ul>

//转换后
<ul>
  <li>third</li>
  <li>first</li>
  <li>second</li>
</ul>

反应会使每个子代变异,而不是意识到可以保持< li >first< /li >和< li >second< /li >。

Keys帮助React确定哪些项目已更改,添加或删除。应该给数组中的元素赋予元素一个稳定的标识。

选择密钥的最好方法是使用一个字符串来唯一标识其兄弟之间的列表项。通常会使用数据中的ID作为密钥:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

当没有稳定ID用于渲染项目时,可以使用项目index作为Keys作为最后的手段:

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

如果项目可以重新排序,我们不建议使用index作为Keys,因为这会很慢。

或者将内容的某些部分哈希生成一个密钥。关键只是在兄弟姐妹中是独一无二的,而不是全局唯一的。

1. 提取组件带Keys (Extracting Components with Keys)

Keys在周围数组的上下文中才有意义。

function ListItem(props) {
  // Correct! There is no need to specify the key here:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Correct! Key should be specified inside the array.
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

一个很好的经验法则是map()调用中的元素需要键。

2. Keys在同级元素中是唯一的 (Keys Must Only Be Unique Among Siblings)

数组中使用的Keys在其兄弟之间应该是唯一的。 然而,它们不需要是全局唯一的。 当我们生成两个不同的数组时,我们可以使用相同的键:

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  return (
    <div>
      {sidebar}
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

Keys作为React的提示,但不会传递给您的组件。如果组件中需要相同的值,用不同名称作为prop显式传递:

  const content = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id} id={post.id} title={post.title}>
          {post.content}
        </li>
      )}
    </ul>
  );

渲染后的Blog组件可以看到props.id,却看不到props.key。

3. 在JSX中嵌入map() (Embedding map() in JSX)

JSX允许将任何表达式嵌入到花括号中,所以可以内联map()结果。

转载于:https://www.cnblogs.com/xmyun/p/6963112.html

多角色体系 支持管理员、商家、消费者三种角色,权限分级管控: 管理员:负责平台整体配置、用户审核、数据监控等全局操作。 商家:管理店铺信息、发布商品、处理订单、回复评价等。 消费者:浏览商品、加入购物车、下单支付、评价商品等。 实现用户注册(手机号 / 邮箱验证)、登录(支持密码 / 验证码 / 第三方登录)、个人信息管理(头像、收货地址、密码修改)。 权限精细化控制 商家仅能管理自家店铺及商品,消费者仅能查看和购买商品,管理员拥有全平台数据访问权限。 二、商品管理功能 商品信息维护 商家可发布商品:填写名称、分类(如服饰、电子产品)、子类别(如手机、笔记本)、规格(尺寸、颜色、型号)、价格、库存、详情描述(图文)、物流信息(运费、发货地)等。 支持商品上下架、库存调整、信息编辑,系统自动记录商品状态变更日志。 商品分类与搜索 按多级分类展示商品(如 “数码产品→手机→智能手机”),支持自定义分类体系。 提供智能搜索功能:按关键词(名称、品牌)搜索,支持模糊匹配和搜索联想;结合用户浏览历史对搜索结果排序(优先展示高相关度商品)。 商品推荐 基于用户浏览、收藏、购买记录,推荐相似商品(如 “浏览过该商品的用户还买了…”)。 首页展示热门商品(销量 TOP10)、新品上架、限时折扣等推荐列表。 三、订单与交易管理 购物车与下单 消费者可将商品加入购物车,支持修改数量、选择规格、移除商品,系统自动计算总价(含运费、折扣)。 下单流程:确认收货地址→选择支付方式(在线支付、货到付款)→提交订单→系统生成唯一订单号。 订单处理流程 订单状态跟踪:待支付→已支付→商家发货→物流运输→消费者收货→订单完成,各状态变更实时通知用户。 商家端功能:查看新订单提醒、确认发货(填写物流单号)、处理退款申请(需审核理由)。 消费者端功能:查看订单详情、追踪物流、申请退款 / 退货、确认收货。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值