簡體   English   中英

React鍵如何工作?

[英]How does React key works?

 import React from 'react' import ReactDOM from 'react-dom' class App extends React.Component{ constructor(props) { super(props) this.state = { list: [{id: 1,val: 'aa'}, {id: 2, val: 'bb'}, {id: 3, val: 'cc'}] } } click() { this.state.list.reverse() this.setState({}) } render() { return ( <ul> <div onClick={this.click.bind(this)}>reverse</div> { this.state.list.map(function(item, index) { return ( <Li key={item.id} val={item.val}></Li> ) }.bind(this)) } </ul> ) } } class Li extends React.Component{ constructor(props) { super(props) } componentDidMount() { console.log('===did===') } componentWillUpdate(nextProps, nextState) { console.log('===mount====') } render() { return ( <li> {this.props.val} <input type="text"></input> </li> ) } } ReactDOM.render(<App/>, document.getElementById('app')) 

當我將key設置為item.id ,我設置了三個輸入標簽abc

當我單擊反向時,組件Li將安裝,輸入將反向

當我將鍵更改為index ,當我單擊反向時,Li組件將更新,並且輸入標簽不會更改,

我想知道它是怎么發生的? 是否有人發現密鑰的工作原理?

正如@DuncanThacker解釋的那樣,該key用於標識唯一元素,以便在2個渲染過程之間,React知道元素是新事物還是更新事物。 請記住,React會比較每個渲染以確定DOM中實際發生了什么變化。

現在解釋一下您所看到的行為:

當我將key設置為item.id ,我設置了三個輸入標簽a, b, c

當我單擊反向時,組件Li將安裝,輸入將反向

當使用id作為key您可以對數組重新排序,但是React只會在一次創建和安裝節點。 您正在componentWillUpdate內部輸出===mount=== ,這就是為什么您看到誤導性輸出的原因,但是React只更新節點(根據需要移動它們)。 內部input的狀態也跟隨每個<Li>組件到達其新位置,因為React正確地理解了<Li> 移動 ,而不是簡單地用不同的內容重新繪制。

當我將鍵更改為index ,當我單擊反向時,組件Li更新,並且輸入標簽不會更改

當您使用index作為key React有效地將每個渲染過程視為以相同的順序渲染數組,但內容不同,因為無論數組內容按什么順序,每個元素的key都是相同的index 。這也是內部input即使val標簽在不同的位置呈現,它也保持在同一位置。 這就是為什么您不應該使用index作為key

您可以這樣說明:

|-----------------------|---------------------|--------------------------|
|        Before         |        After        |          Change          |
|-----------------------|---------------------|--------------------------|

陣:

|-----------------------|---------------------|--------------------------|
| { id: 1, val: "A" }   | { id: 3, val: "C" } | Moved from last to first |
| { id: 2, val: "B" }   | { id: 2, val: "B" } | None                     |
| { id: 3, val: "C" }   | { id: 1, val: "A" } | Moved from first to last |
|-----------------------|---------------------|--------------------------|

index渲染key

|-----------------------|---------------------|--------------------------|
| <Li key=0 val="A">    | <Li key=0 val="C">  | Val changed "A" to "C"   |
| <Li key=1 val="B">    | <Li key=1 val="B">  | None                     |
| <Li key=2 val="C">    | <Li key=2 val="A">  | Val changed "C" to "A"   |
|-----------------------|---------------------|--------------------------|

item.id渲染key

|-----------------------|---------------------|--------------------------|
| <Li key=1 val="A">    | <Li key=3 val="C">  | Moved from bottom to top |
| <Li key=2 val="B">    | <Li key=2 val="B">  | None                     |
| <Li key=3 val="C">    | <Li key=1 val="A">  | Moved from top to bottom |
|-----------------------|---------------------|--------------------------|

簡介: 您應該始終將id或其他唯一元素標識符用作key

另請參閱: https : //medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

React使用“ key”屬性來確定是渲染組件的全新實例,還是更新現有實例。 因此,使用項目ID作為鍵將意味着該項目的組件不會被破壞並重新創建。 如果將一個新項目添加到列表中,它將創建一個新組件,如果刪除一個項目,它將破壞舊的組件,但是如果更新一個項目而不更改其ID,該組件只會更新。

它對於動態列表很有用,因為它可以減少裝入的組件從渲染一個列表項切換到渲染另一個列表項的怪異情況,而實際上它應該是一個全新的組件實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM