列表和关键字

作者: 编码的哲哲 | 来源:发表于2017-02-16 17:44 被阅读36次

首先,让我们回顾一下你是如何用javascript来转换一个列表。在下面的代码中,我们用map函数来使得一个数字数组中的数加倍并且将它打印到控制台:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

上面这段代码将在控制台打印出[2,4,6,8,10],在react中将数组转化为列表的方法和上面的方法类似。

渲染多个组件

你可以创建一个element的集合并把它们包裹在打括号中,下面的代码用map函数将数组中的数字全部转换成li元素,最后将它保存到listItems数组中:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

我们将listItems数组中的元素插入到ul节点中,然后将其渲染到dom上:

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

上面的代码在屏幕上输出了标为1-5的数字列表。

基本列表组件

通常情况下,你需要在一个组件中渲染一个列表,我们可以重写上面的例子,让创建的组件接收这个数字数组,然后返回一个无序列表:

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。当你创建列表是,必须为每一个项目指定特殊的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')
);

关键字

关键字可以帮助react确定哪些列表项被改变,添加或者移除。关键字应该被指定给列表中的每一项以便它们有一个确定的ID:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

你通常会从你的数据中获取ID来为每一项指定关键字:

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

如果你没有一个确定的ID赋给列表项目的话,你可以使用列表的索引值来当作它的关键字:

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

如果这些列表项会被重新排序的话,我们并不建议你使用索引值来当作其关键字,因为这样会使得渲染变的缓慢。

基于关键字抽象组件

关键字仅仅在在包裹它的数组中起作用。比如,如果你抽象出一个名为ListItem的组件,你应该将关键字添加在ListItem的声明上,而不是在LIstItem组件中绑定关键字:

  • 错误的用例
function ListItem(props) {
  const value = props.value;
  return (
    // Wrong! There is no need to specify the key here:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Wrong! The key should have been specified here:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
  • 正确的用例
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函数中绑定关键字 **

一个列表中的列表项的关键字是唯一的

在一个列表中,所有列表项的关键字必须是唯一的,当然,这仅仅在这个列表中如此,全局范围内的列表项的关键字不必全都不一样。我们可以将两个相同的关键字用在不同的数组中:

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {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')
);

关键字为React提供了一个追踪的属性,你不需要将它传递到组件内部,如果在你的组件内部需要这个关键字的值,你可以将它赋值给不同的命名变量并通过prop传递到组件内部:

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

在上面的例子中,Post组件可以取得props,id的值,但是取不到props.key的值。

在JSX中插入map函数

在上面的例子中我们定义一个ListItems的变量并将其插入到JSX中:

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

JSX允许我们将表达式插入其中,所以我们可以这样写:

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

有时候,上面的表达式是十分简洁的,但是也有些许困惑,就像在javascript里面一样。现在,是使用这种简洁的方式呢,还是像前面的代码一样将其抽象成一个变量呢,完全取决于你。还有,若是map函数中的嵌套的话,将嵌套的东东抽象成一个组件是很棒的实践方式。

相关文章

  • Elixir-集合

    列表、元组、关键字列表(keywords)、图(maps)、字典和函数组合子(combinators) 目录 列表...

  • 列表和关键字

    首先,让我们回顾一下你是如何用javascript来转换一个列表。在下面的代码中,我们用map函数来使得一个数字数...

  • python 入门 第5篇: 数据类型3 - 列表、元组类型

    0. 什么是列表? 什么是元组? 在python中, 列表以关键字list表示, 元组则以关键字tuple表示 先...

  • Java关键字

    关键字列表: abstract boolean break byte case ...

  • yum命令

    yum list:查询所有可用软件包列表yum search 关键字:搜索服务器上所有和关键字相关的包yum...

  • Python基础--对列表进行增删改

    列表新增,调用append方法列表删除,关键字del修改列表,找到元素位置并赋值 代码示例: 打印结果:

  • Java关键字和保留字

    Java 关键字和保留字列表如下,不要使用这些值作为变量名。true/false/null,虽然看起来像关键字,但...

  • 【数据结构】散列表的插入和查找(C++实现)

    基本概念 散列表:散列表存储了各个关键字key及其地址。 散列函数:p=H(key),关键字key到其地址的映射。...

  • 自动生成文章

    介绍 根据关键字列表,自动生成相关文章,并以关键字和时间为文章名保存在本地。具体见以下截图,点击main.exe自...

  • 列表与生成内容

    列表类型 list-style-type 可以继承 关键字 效果 disc:空心圆作为列表项标志(默...

网友评论

    本文标题:列表和关键字

    本文链接:https://www.haomeiwen.com/subject/xijhwttx.html