react隨筆7 列表&Keys

列表 & Keys

在JavaScript中map()函數(shù)可以對(duì)數(shù)組中的每一項(xiàng)元素進(jìn)行定義操作,比如對(duì)數(shù)組中的元素都翻倍:

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

那么輸出的結(jié)果是[2,4,6];
在React中,可能需要的操作是把數(shù)組轉(zhuǎn)換成數(shù)列元素的過程,可以認(rèn)為是*React元素的數(shù)組。

渲染多個(gè)組件

比如說現(xiàn)在有一個(gè)數(shù)組[1,2,3],可能經(jīng)過渲染后需要的是一個(gè)元素?cái)?shù)組,如多個(gè)<li>1</li>這種,如下:

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

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

如下圖:


image.png

基礎(chǔ)列表組件

如果需要渲染這種列表,最好是將列表渲染到一個(gè)組件中,進(jìn)行了組件的抽象。
根據(jù)上邊的例子,其實(shí)就是將數(shù)組轉(zhuǎn)變成列表元素的過程封裝到一個(gè)組件中,組件接受一個(gè)numbers數(shù)組作為參數(shù),最后渲染后輸出一個(gè)列表。如下:

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

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

但這樣其實(shí),在返回的列表元素中,每個(gè)元素應(yīng)該指定一個(gè)key,如:

numbers.map(number => <li key="abc">{number}</li>);

key值建議是一個(gè)字符串,并且在這個(gè)列表中是唯一的。

Keys

Keys可以在DOM中的某些元素被增加或者刪除的時(shí)候幫助React識(shí)別哪些元素發(fā)生了變化。在一個(gè)列表中,每個(gè)元素最好擁有唯一的字符串形式的key值。當(dāng)然如果沒有具體的值來作為key值時(shí),可以使用列表元素的序號(hào)索引作為key值。

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

關(guān)于Keys的深度解讀和算法原理,可以參考深度解析key的必要性

元素的key只有放在其環(huán)繞數(shù)組的上下文中才有意義。
比如,提取了一個(gè)ListItem組件,那么key應(yīng)該放在<ListItem />這個(gè)元素上,而不是ListItem中的<li>元素上。

  • 不正確是使用方式
function ListItem(props) {
  const value = props.value;
  return (
    // 錯(cuò)啦!你不需要在這里指定key:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    //錯(cuò)啦!元素的key應(yīng)該在這里指定:
    <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) {
  // 對(duì)啦!這里不需要指定key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 又對(duì)啦!key應(yīng)該在數(shù)組的上下文中被指定
    <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')
);

一個(gè)好的大拇指法則:元素位于map()方法內(nèi)時(shí)需要設(shè)置鍵屬性。
key的值需要在同一個(gè)列表中也就是兄弟元素之間保持唯一即可,不用全局保持唯一。
不過需要注意的是,key是作為給React提示的,不會(huì)傳遞給組件,也就是使用組件的props對(duì)象是拿不到key值的。如下圖:

image.png

可以看到執(zhí)行結(jié)果,冒號(hào)":"后面的值并沒有輸出。
如上圖中的代碼,可以將map()函數(shù)嵌入到JSX語法的大括號(hào){}中。
image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容