8.React中文之列表和键

首先,让我们回顾一下在JavaScript中如何给list变形的。

如下述代码,我们用map()函数循环numbers数组将其中的值加倍。我们给map()返回的新数字组分配加倍的值并打印它:

const numbers=[1,2,3,4,5];

const doubled=numbers.map((number)=>number*2);

console.log(doubled);

这些代码打印[2,4,6,8,10]到平台上。

在React中,将数组转换成元素列表几乎是完全相同的事。

渲染多个组件

你可以创建元素集合用{}括住。以下,我们用JavaScript的map()函数遍历numbers数组。我们为每个项返回一个<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')

);

在CodePen上试试吧。

这些代码展示了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”是必须包含的特殊字符串属性。在下一节我们将讨论它为什么很重要。

让我们在numbers.map()函数中为我们的列表项声明一个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')

);

在CodePen上试试吧。

键帮助React确定哪些项已经改变,添加或移除。把键赋给数组中元素给其一个有状态的标识。

const numbers=[1,2,3,4,5];

const listItems=numbers.map((number)=><li key={number.toString()}>{number}</li>);

挑选key的最好方法是使用一个唯一标识列表集合中项的字符串。大部分情况下,你可以从你的数据中用IDs作为Keys:

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

渲染的项没有IDs时,你只能用项指针作为key:

const todoItems=todos.map((todo,index)=>

    //Only do this if items have no stable IDs

    <li key={index}>

       {todo.text}

    </li>

);

We don`t recommend using indexes for keys if the items can reorder,as that would be slow.You may read an in-depth explanation about why keys are necessary if you`re interested.

如果项需要排序,我们不推荐用指针最为键,因为这样会慢。如果你感兴趣,可以阅读为什么键是必须的深入解读。

提取带键的组件

键只有在数组的上下文中才有意义。

例如,提取一个ListItem组件,应该保证在数组中<ListItem/>元素上的键而不是ListItem本身的根元素<li>上。

例子:错误的键使用

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')

);

在CodePen上试试吧。

最好的做法是在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')

);

在CodePen上试试吧。

Keys serve as a hint to React but they don`t get passed to your components.If you need the same value in your component,pass it explicitly as a prop with a different name:

键对React起暗示作用但是他们不能传递给组件。如果在组件中你需要相同的值,明确以不同的属性名传递。

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允许用大括号包裹任何表达式,所以我们内联map()结果:

function NumberList(props){

    const numbers=props.numbers;

    return(

           <ul>

                {numbers.map((number)=>

                         <ListItem key={number.toString()} value={number} />

                ) }

           </ul> 

    );

}

在CodePen上试试吧。

有时这样写代码更清晰,但是这种风格可能会被滥用。和用JavaScript一样,由你来决定是否值得提取一个变量以增强可读性。注意map()函数体如果嵌套太深,那就是提取组件的好时机到了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值