2016-10-11 20 views
7

我讀componentDidMount被初始渲染只調用一次,但我看到它得到了多次渲染。爲什麼在react.js&redux中多次調用componentDidMount?

看來我創建了一個遞歸循環。

  • componentDidMount調度動作在接收到的數據來獲取數據
  • ,它觸發成功動作到的數據存儲在終極版的狀態。
  • 父發生反應部件連接到終極版存儲和具有mapStateToProps對於剛剛在上述步驟
  • 父使得子組件(這是通過可變編程選擇的)
  • 子組件的componentDidMount被再次調用改變了條目
  • 它dispaches行動來獲取數據

我認爲這是發生了什麼。我可能是錯的。

如何停止循環?

下面是以編程方式呈現子組件的代碼。

function renderSubviews({viewConfigs, viewConfig, getSubviewData}) { 

    return viewConfig.subviewConfigs.map((subviewConfig, index) => { 
    let Subview = viewConfigRegistry[subviewConfig.constructor.configName] 
    let subviewData = getSubviewData(subviewConfig) 

    const key = shortid.generate() 
    const subviewLayout = Object.assign({}, subviewConfig.layout, {key: key}) 
    return (
     <div 
     key={key} 
     data-grid={subviewLayout} 
     > 
     <Subview 
      {...subviewData} 
      /> 
     </div> 
    ) 
    }) 
} 

回答

17

一個組件實例只會掛載一次,並在被刪除時卸載。在你的情況下,它會被刪除並重新創建。

key prop的要點在於幫助React找到相同組件的以前版本。這樣它可以用新的道具更新以前的組件,而不是創建一個新的道具。

React通常可以在沒有密鑰的情況下正常工作,例外情況是帶有項目的列表。它需要一個關鍵字,以便在重新排列,創建或刪除項目時保持跟蹤。

就你而言,你明確地告訴React你的組件與前一個不同。你在每個渲染上都給了一個新的密鑰。這迫使React將先前的實例視爲已被刪除。該部件的任何兒童也將被卸下並拆除。

你應該做的是不(隨時)隨機生成密鑰。密鑰應始終基於組件正在顯示的數據的標識。如果它不是一個列表項,你可能不需要一個密鑰。如果它是一個列表項,那麼使用從數據身份派生的密鑰(如ID屬性)或多個字段的組合可能更好。

如果產生一個隨機密鑰本來就是正確的事情,那麼React就會爲你處理這件事。

您應該將您的初始提取代碼放在您的React樹的根目錄下,通常是App。不要把它放在隨機的孩子身上。至少你應該把它放在你的應用程序的整個生命週期中存在的組件中。

把它放在componentDidMount中的主要原因是它不能在服務器上運行,因爲服務器端組件永遠不會被掛載。這對通用渲染很重要。即使你現在沒有這樣做,你以後可能會這樣做,併爲此做好準備是一種最佳做法。

+0

哇,謝謝你的回答。我回來重新說我的問題,因爲我問的問題不清楚,這裏的答案解釋了爲什麼它發生了。謝謝 – eugene

+1

我從這個答案中學到了很多!從反應非常優雅的方法 – cbartondock

相關問題