将React组件移到另一个父对象

时间:2019-08-05 14:47:26

标签: javascript reactjs

我目前正在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组件。

2 个答案:

答案 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>
  )
}

对您的ParenLeftParentRight使用相同的方法。或创建通用的Parent组件。并像<Paren left/><Paren right/>这样使用它。有关如何使用条件的信息,请参见Figure

您不能使用ReactDOM.createPortal()将某些东西从反应树的一个位置渲染到另一个位置-因为门户网站是另外一个反应树。要将某物从一个反应位置渲染到另一个反应位置,您需要react-through