我目前正在React中创建一个用于学习的国际象棋游戏。我遇到的是将React组件从一个父对象移动到另一个父对象,并保留了道具。我已经阅读了ReactDOM.createPortal(),但似乎无法正常工作。
为了说明这个问题,我创建了一个带有两个容器的简单React应用,其中一个容器中有一个按钮。目的是在单击按钮时将按钮移到另一个容器。
export default class ParentLeft extends React.Component{
render(){
return(
<div className="container">
<Button />
</div>
);
}
}
export default class ParentRight extends React.Component{
render(){
return(
<div className="container"></div>
);
}
}
在此示例中,简单的解决方案是在ParentRight组件中调用一个函数,并使用setState()在其中渲染Button组件。这不是我正在寻找的解决方案。在我的国际象棋游戏中,我不知道需要移动哪种React组件。
答案 0 :(得分:0)
我的建议是重新考虑程序的流程。通常,在没有上下文和/或redux或其他状态管理器帮助的情况下,您不会看到互不相关的组件相互通信。通过不相关的组件,我们可以将它们定义为不共享相对紧密的共同祖先的那些组件,例如包装器组件,通过状态控制其props.children。
尽管我相信您可以通过Portal获得所需的结果,但是它们通常用于呈现模式和类似的组件,例如对话框,消息等。
考虑到这些事实,遵循Facebook建议的自上而下的推荐方法是:
export default class MainWrapper extends React.Component {
state = {
buttonAtLeft: true,
}
changeButtonPosition = () => {
this.setState({ buttonAtLeft: !this.state.buttonAtLeft });
}
render() {
const { buttonAtLeft } = this.state;
return (
<div>
<ParentLeft>
{
buttonAtLeft
? <Button onClick={this.changeButtonPosition} />
: undefined
}
</ParentLeft>
<ParentRight>
{
buttonAtLeft
? undefined
: <Button onClick={this.changeButtonPosition} />
}
</ParentRight>
</div>
);
}
}
只需记住更新ParentRight / Left组件,使它们在其render方法上渲染props.children:
render() {
return (
<div className="container">
{this.props.children}
</div>
)
}
说明:
MainWrapper现在负责更改按钮的位置,并且还充当了ParentLeft和ParentRight之间交换通信的桥梁。其方法changeButtonPosition只需切换在MainWrapper的状态下找到的boolean buttonAtLeft。
随后,我们基于state.buttonAtLeft进行条件渲染,在适当的位置渲染按钮。
答案 1 :(得分:0)
名为container
的顶部组件必须具有定义图形及其位置的所有状态。使其成为Bridge
组件:
class Bridge = () => {
const figures = useState()
const squares = useState()
render board.each(square =>
<Square figure={figure[square]}>
)
}
创建组件Square
:
class Square = ({figure}) => {
render (
<Figure figure={figure}>
)
}
创建组件Figure
:
class Figure = ({figure}) => {
render switch(figure) {
case 'king': return <King/>
case 'queen': return <Quieen/>
default: return null
)
}
现在,如果仅在正方形有数字的情况下才需要正方形按钮,则可以像这样使正方形变成正方形:
class Square = ({figure}) => {
render (`
<React.Fragment>
<Figure figure={figure}>
{figure ? <Button> : null}
</React.Fragment>
)
}
对您的ParenLeft
和ParentRight
使用相同的方法。或创建通用的Parent
组件。并像<Paren left/>
或<Paren right/>
这样使用它。有关如何使用条件的信息,请参见Figure
。
您不能使用ReactDOM.createPortal()
将某些东西从反应树的一个位置渲染到另一个位置-因为门户网站是另外一个反应树。要将某物从一个反应位置渲染到另一个反应位置,您需要react-through