[英]Unable to set the key for react.js components
似乎最瑣碎的任務再次使我的項目停頓了。 這是我的情況:
我在ASP.NET 4.5 MVC 6 SPA中使用react.js。 我的設計使我在三個主要區域使用了react:頂部菜單,側面菜單和主要內容區域。 由於不同區域的時間和負載要求,我有3個獨立的React組件層次結構,每個主要部分一個。 也許那是那里問題的一部分,但是在某個地方,我想到了這是可以接受的。
因此,在某一時刻,我從Web服務中提取了一個頂層菜單節點列表,並將它們綁定到頂層菜單react組件,然后對側面菜單執行相同的操作。 當有人單擊菜單項之一時,它將新數據加載到內容面板區域中,這些是我加載到div中的react組件。
一切工作都按預期進行,直到我嘗試在內容面板中卸載該組件,然后再向其中加載新組件。 當我通過我的div調用ReactDOM.unmountComponentAtNode()
,我得到以下信息:
Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same
數據反應: .0(…)
在這一點上,我有一些疑慮:
其次,我多次嘗試在頂級React組件上設置特定鍵均失敗了。 我閱讀並理解了建議/規則,您在創建鍵時必須在組件外部設置鍵,而不是直接在內部從元素上設置鍵,因此我的組件創建為:
ReactDom.render(<ManageCommunitiesContainer brandData={mcmData} key="manageComms" />, $("#reactRoot")[0]);
我已經為正在使用的三個頂級組件中的每個組件添加了唯一鍵,但是當我在chrome開發人員工具的react插件中檢查它們時,所有這三個組件都具有相同的data-reactid
,即“ 0.0' 。
我已經從內部在子對象上設置了子對象的鍵,在循環內沒有任何問題。 但是在通過javascript添加的頂級組件上,我什么也沒做,導致它們具有有意義的運行時值...一個人必須做什么才能為根組件分配唯一的鍵,從而能夠在以后卸載它們? 因為我無法卸載它們,所以它們堆積在內存中。
謝謝。
React鍵與data-reactid
。 了解React組件與DOM元素不同。 有一篇不錯的React博客文章 ,解釋了Components,Instances和Elements之間的區別。
我要說的是,嘗試手動卸載組件並渲染全新的樹很難。 當您僅執行初始渲染然后處理狀態以使React更新DOM元素時,React的優勢就會顯示出來。
我的第一個建議是嘗試回到單個組件層次結構。 時序要求可以在根組件的狀態下捕獲。 像這樣:
class TopMenu extends React.Component {
render() {
const data = this.props.data;
if (!data) {
return <div>Loading...</div>;
}
// render your menu with the data provided...
return <div>{data}</div>;
}
}
class SideMenu...
class Content...
class Page extends React.Component {
constructor(...args) {
super(...args);
this.state = {
topMenuData: undefined,
sideMenuData: undefined,
contentData: undefined
}
componentDidMount() {
// call ready callback provided via props with this instance
// so someone outside can update our state when data loads
this.props.ready(this);
}
render() {
return (
<div>
<TopMenu data={this.state.topMenuData} />
<SideMenu data={this.state.sideMenuData} />
<Content data={this.state.contentData} />
</div>);
}
}
// main js code
function pageMounted(page) {
// register callbacks with your code that is loading data from
// the server.
topMenuLoader.then(data => page.setState({ topMenuData: data }));
sideMenuLoader.then(data => page.setState({ sideMenuData: data }));
contentLoader.then(data => page.setState({ contentData: data }));
}
React.render(<Page ready={pageMounted} />, rootElement);
通過這種風格,最終您可能可以將加載邏輯移至React組件層次結構本身內的某個位置,並擺脫使外界更新狀態的ready
回調。
即使由於約束而無法創建單個組件層次結構,也可以使用該ready
回調的相同基本思想來創建3個您從未銷毀的頂級React層次結構,而僅在需要更改setState
通過setState
提供新數據呈現什么。
幾天后的午夜過后,答案:似乎與我始終使用html包裝標簽相同的元素ID有關。
我認為總是將包含反應.clear()
的元素指定為具有相同的id是明智的,因此我可以以編程方式找到它,然后卸載組件,然后將.clear()
內容平整以便准備好進行新的標記,無論是否做出反應。
最終,我看到我前一段時間做的一些測試使用的是唯一元素id並按計划進行,因此我現在對它們進行了足夠的更改,以至於相信這是有影響的。 像以往一樣,我還不是100%清楚為什么我的方法會導致它窒息,似乎可以從我坐着的地方采取足夠的合法行動,但是...有。
希望它能在某個時候對某人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.