React中文文档之Lists and Keys

    xiaoxiao2021-08-16  166

    Lists and Keys 首先,让我们回顾一下,在js中如何变换列表。 下面给出的代码,我们使用 'map()' 函数作用一个 'numbers' 数组,并且使数组中的元素值*2.我们分配由 'map()' 返回的新数组给变量 'doubled',并且在console中输出: const numbers = [1, 2, 3, 4, 5]; const doubled = number.map((numer) => number * 2); console.log(doubled); 这段代码在console中输出:[2, 4, 6, 8, 10] 在React中,变换数组为元素列表,同js中差不多是一样的。 渲染多个组件 你可以构建元素集合,并且通过使用 '{}',在JSX中来引入它们。 下面,我们通过js的 'map()' 函数来循环 'numbers' 数组。对数组的每个条目,返回一个 '<li>' 元素。最终,我们分配元素结果数组给 'listItems': const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); 我们在一个 '<ul>' 元素内包含整个 'listItems' 数组,并且渲染为DOM: ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('root') ); 这段代码展示了一个1-5数字的无序列表 基础列表组件 通常我们希望在一个组件内部渲染列表. 我们重构值钱的例子为一个组件,接收一个 'numbers' 的数组,并且输出一个元素无序列表: 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' 是一个特殊的字符串属性,当创建元素列表时需要引入。在下个小结,我们将讨论为什么它很重要。 让我们分配一个 'key' 给我们的列表条目,在 'numbers.map()' 内部,并且修复这个丢失的key的问题。 function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> // 这里新增了key属性 {number} </li> ); return ( <ul>{listItems}</ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('root') ); keys keys帮助React识别列表中哪个条目修改过、新增的或者被移除。数组内的元素应该给出keys属性,以赋予元素一个稳定的标识: 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> ); 如果列表条目可能被重排,我们不建议使用条目索引作为key,因为这样会很慢(React计算条目哪些被修过、是新增的,还是移除了哪些条目,比较缓慢)。如果你感兴趣,可以阅读 'in-depth explanation about why keys are necessary' 这节。 使用keys来提取组件 keys只有在数组的上下文中才有意义。 例如:如果你提取一个 'ListItem' 组件,你应该保证 <ListItem> 元素上的key在这个数组中,而不是在根 <li> 元素在 'ListItem' 自身上。 不正确的key的使用: function ListItem(props) { const value = props.vaue; return ( // 错误!这里不需要指定key <li key={value.toString()}> {value} </li> ); } function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // 错误!key应该在这里被指定 <ListItem value={number} /> ); return ( <ul> {listItem} </ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOm.render( <NumberList numbers={numbers} />, document.getElementById('root') ); 正确的key的使用: function ListItem(props) { // 正确!这里不需要制定key return <li>{props.value}</li> } function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // 正确!key应该在数组中被指定 <ListItem key={number.toString()} value={number} /> ); return ( <ul> {listItem} </ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('root') ); 一个好的经验法则是:在 'map()' 调用的内部元素需要key。 在兄弟元素间,必须保证key是唯一的 数组内部使用的key,在它的兄弟元素之间必须是唯一的。但是它们没必要是全局唯一。不同数组间,是可以使用相同的key的: 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') ); keys作为一个提示服务于React,但它们并不传递给你的组件。如果在你的组件中需要同样的值,将 key 作为一个 prop(使用不同的名字) 来明确地传递它: const content = post.map((post) => <Post key={post.id} // key只是React用于检测列表条目的变化(不会供我们内部props使用) id={post.id} // 我们再定义一个id,内部就可以通过 props.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> {listItem} </ul> ); } JSX允许在 '{}' 内嵌入任意表达式,因此我们可以内联 'map()' 的结果: function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <ListItem key={number.toString()} value={number} /> ); return ( <ul> {numbers.map((number) => <ListItem key={number.toString()} value={number} /> )} </ul> ); } 有时候,这样更清晰明了,但是这种方式有可能被滥用。就像在js中,它取决于你,来决定为了可读性,是否值得提取一个变量。牢记:如果 'map()' 体也是嵌套的,这可能是一个提取组件的好时机。
    转载请注明原文地址: https://ju.6miu.com/read-676432.html

    最新回复(0)