對於React中key的作用,官方沒有給出詳細的解讀,只提到在List中需要給key賦值來區分每一條記錄,
http://blog.csdn.net/code_for_free/article/details/50514259里講解了key的使用場景,
http://taobaofed.org/blog/2016/08/24/react-key/從三方面講了List組件中key存在的原因和List之外使用key作為trick簡化代碼邏輯,本文以List中新增元素為例,從List子組件生命周期函數的調用角度分析了可以使用的更新方案及key的作用。
通常認為當 React 元素內包含數量或順序不確定的子元素時,需要提供 key 屬性來定位元素是否已經存在。在實際使用中可以認為 key是一個接口,用來對哪些元素新建,哪些元素刪除。
比如現有一個List,每個組件新增時需要用ID向后端發起請求(函數應該放在
didmount里),當前id數組的狀態是[0,1],如何在原來的基礎上變成[2,3,0]呢,可以有以下幾種方法:
1,刪除原來的數組,再添加3個元素,分別設為2,3,0。不需要使用key來標識元素是否存在,這很明顯是低效的,而且這會帶來副作用(生命周期里init,didmount,willumount都會調用),,
2,直接在后面添加一個元素,值分別設為2,3,0.沒有key,用數組下標,最后一個元素0是新增的,需要調用組件的(
init,didmount),
didmount里接收的是0並向后端發請求
3,按值查找,對0保持不變,刪除1,新增2,3,這符合我們想要的邏輯,但是我們還沒有告訴react值是什么,List里可能是一個復雜的組件,所以react提供了一個key,讓我們自己設置這個元素什么時候需要重新掛載。
下面看其中一個應用場景
點擊界面上的按鈕add item,在下面的列表增加一個一條記錄,記錄掛載時在控制台輸出自身的ID,數據的數組是按時間正序,視圖按時間逆序顯示
import React, { Component } from 'react';
class Item extends Component {
componentDidMount(){
console.log(this.props.text);
}
render(){
return ( <li>{this.props.text}</li>)
}
componentDidMount(){
console.log(this.props.text);
}
render(){
return ( <li>{this.props.text}</li>)
}
};
class App extends Component {
constructor (){
super()
this.state={arr:[0,1]};
this.addItem=this.addItem.bind(this)
}
addItem(){
var arr=this.state.arr.slice(0);
arr.push(arr.length);
this.setState({arr:arr});
}
render() {
var arr=this.state.arr.slice(0);
arr.reverse();
return (
<div className="App">
<button onClick={this.addItem}>add item</button>
<ul>
{arr.map((item,index)=>{
constructor (){
super()
this.state={arr:[0,1]};
this.addItem=this.addItem.bind(this)
}
addItem(){
var arr=this.state.arr.slice(0);
arr.push(arr.length);
this.setState({arr:arr});
}
render() {
var arr=this.state.arr.slice(0);
arr.reverse();
return (
<div className="App">
<button onClick={this.addItem}>add item</button>
<ul>
{arr.map((item,index)=>{
return <Item key={index} text={item}/>
})}
</ul>
</div>
);
}
}
</ul>
</div>
);
}
}
export default App;
當APP的render里不設置key 或者key={index} 時,每次新掛載的節點都是0(其他節點能在willreceiveprops中接檢測到改變),因為逆序之后,最后一個元素是0,而這個元素的key之前是沒有的,所以要新增節點。要實現目標,需要通過在App的render中設置
key={arr.length-index}(因為本例的數組簡單,設key={item}也可以),告訴react對應的位置不需要重新掛載。
PS:快速新建React程序用create-react-app挺方便的,不用配置就可以使用熱更新,使用方法:
https://github.com/facebookincubator/create-react-app
