我面临一个问题,即我的组件只有在封装在div
中时才能更新。
我有一个switch statement
来呈现孩子的不同版本。当我用div
包装第二个案例时,似乎一切都正常,但如果这个div
不存在,它就不会像预期的那样工作。_getCurrentInputState
和selectedBlock
似乎没有按应有的方式更新。
const Parent= () => {
{/* ... */}
const _renderEditorPanel = () =>{
const currentBlockType = blockList[selectedBlock].type
switch(currentBlockType){
case 'description': return (
<EditorPanel
currentBlockType={'description'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
)
case 'skills_and_requirements': return (
<div> {/* <<<<<<<<<<<<<<<<<<<<<<<< This is needed to really update the child?
*/}
<EditorPanel
currentBlockType={'skills_and_requirements'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
</div> {/* <<<< and this.*/}
);
default: return (
<EditorPanel
currentBlockType={'default'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
);
}
}
return (
<StyledJobEditor>
{_renderEditorPanel()}
<div className="preview_panel">
<div>
<button onClick={
() => setSelectedBlock("1")
}>1</button>
<button onClick={() => setSelectedBlock("2")}>2</button>
<button onClick={() => setSelectedBlock("0")}>0</button>
</div>
{/*
The sidebar will be an arraw of block. We should expect to use the .map function here.
*/}
</div>
</StyledJobEditor>
);
}
我相信您看到这种情况的原因是react无法判断它应该装载同一组件的新实例。通过将一个包在div
中,react看到了它的不同,并重新安装了所有内容。否则,它只是将其视为道具更改。
如果没有看到EditorPanel
的实现,我就无法提供更多的见解,但我猜您未更改的道具只在挂载或类似的东西上设置了一次。
就像映射元素一样,您可以为交换机中的每个元素提供一个key
,以通知react每个元素都是唯一的。
switch (currentBlockType) {
case 'description': return (
<EditorPanel
key="description" // Add this
currentBlockType={'description'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
)
case 'skills_and_requirements': return (
<EditorPanel
key="skills_and_requirements" // Add this
currentBlockType={'skills_and_requirements'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
)
default: return (
<EditorPanel
key="default" // Add this
currentBlockType={'default'}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
)
首先,您根本不需要切换用例。其次,您返回的是html,所以它是一个组件,而不是一个方法,所以方法名称以大写字母开头。您可以将代码缩减为
const RenderEditorPanel = () => {
const currentBlockType = blockList[selectedBlock].type || 'default';
return (
<EditorPanel
currentBlockType={currentBlockType}
selectedBlock={selectedBlock}
_getBlock={_getBlock}
_getCurrentInputState={_getCurrentInputState}
_setCurrentInputState={_setCurrentInputState}
/>
)
}
同样,当我们使用这个组件时,它应该像下面一样
<RenderEditorPanel />