通过级别传递数据 - 最后打开模态对话框

Pass data through levels - open Modal dialog at the end

我为此苦思良久,需要一些帮助。

从根本上说,我想要做的是我有两层组件 - 最后一层应该在您单击它时打开一个模态对话框。因为 React 的想法是组件应该只改变它自己的状态,所以我想向上传播那个数据并设置那个变量。

布局如下。 FirstLevel.jsx 文件是我的层次结构的顶部。其后是 SecondLevel.jsxThirdLevel.jsx,这是实际文本被点击的地方。

我不知道任何语法。不确定 onUserInput 是要使用的正确属性还是 handleUserClick 是内置的东西还是用户定义的东西。这里的想法是我试图将回调函数 handleUserClick 传播到 SecondLevel 中。到目前为止这是对的吗?

FirstLevel.jsx

export default class FirstLevel extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dialogActive: ''
        };
        this.handleUserClick = this.handleUserClick.bind(this);
    }

handleUserClick(dialogActive) {
    this.setState({
        dialogActive: dialogActive
    });
}

render() {
    <SecondLevel onUserInput={this.handleUserClick}/>
}

现在,在 SecondLevel 上,我将回调函数传播到 ThirdLevel。到目前为止,这是正确的做法吗?

SecondLevel.jsx

render () {
    //other logic and tags before this

    <ThirdLevel onUserInput={this.props.onUserInput}/>
}

现在这一关是一团乱麻,我不知道自己在做什么。在单击时,我想设置向下传播的 dialogActive 变量,然后让它向上浮动。我仍然不知道 onUserInput 是否正确,或者参数是否正确。一切都非常模糊,因为它只是通过遵循教程并进行大量谷歌搜索并从各处收集零碎信息而获得的。

ThirdLevel.jsx

export default class ThirdLevel extends React.Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {

        this.props.onUserInput(
            this.dialogActive.value
        );

        //show Modal dialog somehow
    }

    render() {

        return <text ref={(input) => this.dialogActive = true} onClick={this.handleClick}> {this.props.value}</text>;
    }

最后,我想展示一些模态对话框。单击文本需要显示一个模式对话框。模态对话框位于另一个名为 MyModal.jsx

的组件中

ThirdLevel 中,我尝试导入 MyModal 并尝试调用 showModal 函数。没用。然后,我尝试做一些 React.createElement(MyModal) 的东西并渲染它,但那没有用。我忘记了所有其他事情,只是尝试一些东西直到它起作用但它没有。我究竟做错了什么?

MyModal.jsx

export default class MyModal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {show: false};

        this.showModal = this.showModal.bind(this);
        this.hideModal = this.hideModal.bind(this);

    }

    showModal() {
        this.setState({show: true});
    }

    hideModal() {
        this.setState({show: false});
    }

    render() {

        return (
                <Modal
                    {...this.props}
                    show={this.state.show}
                    onHide={this.hideModal}
                    dialogClassName={styles.largeDialogBox}
                >
                //more modal stuff here
           );
     }
}

大图:尝试将单击操作传播回层次结构的顶部以设置某些状态,并且该单击操作需要打开模式对话框。任何帮助将不胜感激。

编辑

我会在 ThirdLevel 中做这样的事情吗?

handleClick() {

    this.props.onUserInput(
        this.dialogActive.value
    );

    //show Modal dialog somehow
    var newmodal = new MyModal(this.props);
    React.render(React.createElement(newModal));
}

render() {
    return <text onClick={this.handleClick}> {this.props.value}</text>;
}

编辑 2

我的 ThirdLevel 渲染函数 returns 这个:

<div>
    <MyModal isDialogActive={this.props.dialogActive} onHideModal={this.props.onUserInput}/>
    <tspan onClick={this.handleClick}> {this.props.value} </tspan>
</div>

当它返回到 SecondLevel 时,它变成:

<text>
    <div>
        <MyModal isDialogActive={this.props.dialogActive} onHideModal={this.props.onUserInput}/>
        <tspan onClick={this.handleClick}> {this.props.value} </tspan>
    </div>
</text>

将东西包裹在 div 中很奇怪,但这是使渲染工作的唯一方法。尽管生成的 DOM 包含所有标签,但显示了实际 tspan 的 none。

我相信这会让您走上正确的道路。

我建议重构一些函数的名称,因为它确实有点令人困惑。 handleUserClick 然后 onUserInput 等等。但是你已经在你的 OP 中提到了。

// First Level
export default class FirstLevel extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dialogActive: false
        };
        this.handleUserClick = this.handleUserClick.bind(this);
    }

  handleUserClick(dialogActive) {
      this.setState({
          dialogActive: dialogActive
      });
  }

  render() {
      <SecondLevel onUserInput={this.handleUserClick}/>
  }
}

// Second Level
...
render () {
    //other logic and tags before this
    <ThirdLevel onUserInput={this.props.onUserInput}/>
}
...

// Third Level
export default class ThirdLevel extends React.Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
      this.props.onUserInput(true);
    }

    render() {

        return (
          <div>
            <MyModal isDialogActive={this.props.dialogActive} onHideModal={this.props.onUserInput} />
            <button onClick={this.handleClick}>Show Modal</button>
          </div>
        )
    }
}

// Modal
export default class MyModal extends React.Component {
    constructor(props) {
        super(props);
        this.hideModal = this.hideModal.bind(this);
    }

    hideModal() {
      this.props.onUserInput(false);
    }

    render() {
        return (
                <Modal
                    {...this.props}
                    show={this.props.isDialogActive}
                    onHide={this.hideModal}
                    dialogClassName={styles.largeDialogBox}
                >
                //more modal stuff here
           );
     }
}

但是我想问的是,为什么您在 FirstLevel 中需要此逻辑,而且它不能在组件树的下方。