我正在尝试做的事情似乎有些不合常规,请耐心等待。
我想使用React Portal将子组件渲染到父组件的DOM节点中。
您可能会想:“这不是门户网站的目的,您应该只在需要的位置呈现孩子。”
您可能是对的,但这是我尝试了许多其他方式后尝试使用的实验方法的简化示例。
无论如何,这是代码:(sandbox here)
const Child = ({ color }) => {
let jsx = <h1>Wow! I am {color}!</h1>;
let node = document.getElementById(color);
return ReactDOM.createPortal(jsx, node);
};
class Parent extends React.Component {
state = {
color: "green"
};
changeColor = () => {
let color = this.state.color === "green" ? "blue" : "green";
this.setState({ color });
};
render() {
return (
<div className="App">
<Child color={this.state.color} />
<button onClick={this.changeColor}>change color</button>
<div className="green" id="green">
I render green stuff:
</div>
<div className="blue" id="blue">
I render blue stuff:
</div>
</div>
);
};
};
问题在于,当Child尝试向其中渲染一些jsx时,尚未渲染Parent组件的“ blue”和“ green” div。所以我得到了错误Target container is not a DOM element
。我使它起作用的唯一方法是将这些div放在根目录下的html文件中。
关于如何使用门户网站尝试做的任何建议?请不要仅仅这样做:
<div className="App">
<button onClick={this.changeColor}>change color</button>
<div className="green" id="green">
I render green stuff:
{this.state.color === 'green' && <Child color='green' />}
</div>
<div className="blue" id="blue">
I render blue stuff:
{this.state.color === 'blue' && <Child color='blue' />}
</div>
</div>
预先感谢您:-)
答案 0 :(得分:1)
是的,所以您的问题是,(此时)您不能(通过它们的ID)查找div,因为它们是由父组件渲染的,并且它们不在您想像的DOM中。 / p>
但是!您可以使用裁判来节省一天!这是一个示例:https://codesandbox.io/s/r78mplox64?fontsize=14
我替换了功能组件的类,因为这些钩子可以使它更清晰。基本上,它所做的全部工作就是将两个ref传递给color div,并且在渲染之后,ref的当前值将指向该节点。挂载的useEffect
将colorNode
的状态设置为蓝色ref(即<div id="blue">
节点)的当前值。
然后,单击按钮仅交换出color变量和color节点。然后,两者都作为prop传递,而colorNode
prop作为门户呈现的节点传递。