2017-04-27 17 views
4

在資源有限的設備中,通過組件池來利用性能是很常見的做法。例如,有一個無限的滾動列表。由於在視口中總是會顯示大約10個組件,因此池中只能有20個組件實例。當用戶向上或向下滾動時,頂部或底部的組件切換到另一側並填充新數據。用這種方式,用戶覺得列表很長,但只需要20個組件實例。如何在React中執行組件池?

使用jQuery和命令式編程,很容易實現這種組件池技巧。但是,在React世界中,UI是聲明性的。

const List = ({listData}) => { 
    return <ul> 
    {listData.map(item => <li>{item}</li>); 
    </ul>; 
} 

該代碼只是聲明有一個要顯示的項目列表。我們的代碼無法控制組件池;我相信React本身會創建DOM池。

那麼,如何實現組件池以獲得更好的性能?

回答

3

React-Virtualized這個庫是React應用程序中使用的虛擬列表的前往實現。它非常優化,我認爲它使用了很多refs和DOM交互來完成它需要做的事情。

這是說,我從來沒有真正試圖實現一個虛擬列表或組件彙集的反應(或其他地方,真的),我可以想象的東西,可能沿着正確的線是一個基本的概念。

在本例中,我們列出了1000個項目,但只想顯示20.首先,您需要在render中完成所有正確的分頁和窗口。假設用戶已經向下滾動了30個項目,所以我們想要顯示項目30-50。通常,當您在React中呈現項目列表時,您可以根據數據中的ID將鍵分配給每個項目,或者作爲後備數組索引。

通常情況下,使用數組索引作爲鍵是不好的,因爲更改內容會使React認爲已經移動了東西。而不是有組件掛載和卸載,就像通常想要的那樣,這些組件會保持掛載狀態,但是會突然收到一組不同的道具。但是,在這種情況下,這似乎是期望的行爲。

所以,沒有經過測試和假設,但依稀似是而非的示例代碼:

render() { 
    const {items} = this.props; 
    const {displaySize, startIndex} = this.state; 

    const itemsToDisplay = items.slice(startIndex, startIndex + displaySize + 1); 

    const renderedItems = itemsToDisplay.map((item, index) => { 
     return <ListItem item={item} key={index} /> 
    }); 

    return (
     <div> 
      {renderedItems} 
     </div> 
    ); 
} 
+3

謝謝你的提及,馬克!關於這個例子的一個小問題是,它會導致不必要的DOM更新,因爲每次開始索引改變時,所有元素都會被更新,每個元素的鍵都會改變。只要池大小穩定,您可以嘗試旋轉鍵(例如'(startIndex + index)%poolSize')。有了RV,我發現把鍵設置爲'startIndex + index'但是YMMV更好。 – brianvaughn

+0

Bah,旋轉鍵應該是'(startIndex + index)%(displaySize + 1)' – brianvaughn

相關問題