小编典典

如何使React.js与zurb一起很好地显示模态形式

reactjs

我正在尝试将zurb显示形式与反应组件集成在一起。到目前为止,下一个代码可以正确显示模式形式:

ModalForm = React.createClass({
  handleSubmit: function(attrs) {
    this.props.onSubmit(attrs);
    return false;
  },

  render: function(){
    return(
      <div>
        <a href="#" data-reveal-id="formModal" className="button">Add new</a>
        <div id="formModal" className="reveal-modal" data-reveal>
          <h4>Add something new</h4>
          <Form onSubmit={this.handleSubmit} />
          <a className="close-reveal-modal">&#215;</a>
        </div>
      </div>
    );
  }
});

Form组件是非常标准的:

Form = React.createClass({
  handleSubmit: function() {
    var body = this.refs.body.getDOMNode().value.trim();
    if (!body) {
      return false;
    }
    this.props.onSubmit({body: body});
    this.refs.body.getDOMNode().value = '';
    return false;
  },
  render: function(){
    return(
      <form onSubmit={this.handleSubmit}>
        <textarea name="body" placeholder="Say something..." ref="body" />
        <input type="submit" value="Send" className="button" />
      </form>
    );
  }
});

问题: 当我在模态表单组件中呈现表单组件并将某些内容输入到表单输入中时,我在控制台异常中看到了Uncaught object。这是一个堆栈:

Uncaught object
  invariant
  ReactMount.findComponentRoot
  ReactMount.findReactNodeByID
  getNode
  ...

如果我只是直接在父组件中渲染表单组件,则一切正常。有人可以帮忙吗?


阅读 226

收藏
2020-07-22

共1个答案

小编典典

简而言之,您做错了,这 不是 在响应中的错误。

如果您使用任何可修改react组件的dom节点的插件,那么它将以一种或另一种方式破坏事物。

相反,您应该做的是使用react本身和互补的CSS,以您希望在模态对话框中使用的方式放置组件。

我建议创建一个使用react的staticscomponent属性定义一个函数包装的组件,renderComponent以便给您一个漂亮的干净函数调用以显示或隐藏react对话框。这是我过去使用过的东西的简化示例。注意:它确实使用jQuery,但是elementById如果您不想要jQuery代码,则可以用对诸如此类之类的标准js
api调用替换jQ 。

window.MyDialog = React.createClass({
    propTypes: {
        title:      React.PropTypes.string.isRequired,
        content:    React.PropTypes.string.isRequired
    },
    statics: {

        // open a dialog with props object as props
        open: function(props) {
            var $anchor = $('#dialog-anchor');
            if (!$anchor.length) {
                $anchor = $('<div></div>')
                    .prop('id', 'dialog-anchor');
                    .appendTo('body');
            }
            return React.renderComponent(
                MyDialog(props),
                $anchor.get(0)
            );
        },

        // close a dialog
        close: function() {
            React.unmountComponentAtNode($('#dialog-anchor').get(0));
        }
    },

    // when dialog opens, add a keyup event handler to body
    componentDidMount: function() {
        $('body').on('keyup.myDialog', this.globalKeyupHandler);
    },

    // when dialog closes, clean up the bound keyup event handler on body 
    componentWillUnmount: function() {
        $('body').off('keyup.myDialog');
    },

    // handles keyup events on body
    globalKeyupHandler: function(e) {
        if (e.keyCode == 27) { // ESC key

            // close the dialog
            this.statics.close();
        }
    },

    // Extremely basic dialog dom layout - use your own
    render: function() {
        <div className="dialog">
            <div className="title-bar">
                <div className="title">{this.props.title}</div>
                    <a href="#" className="close" onClick={this.closeHandler}>
                </div>
            </div>
            <div className="content">
                {this.props.content}
            </div>
        </div>
    }
});

然后,您通过调用以下方法打开一个对话框:

MyDialog.open({title: 'Dialog Title', content: 'My dialog content'});

并用关闭

MyDialog.close()

该对话框始终直接附加在ID为“ dialog-
anchor”的主体下的新dom节点。如果您在一个对话框已经打开的情况下打开对话框,它将仅基于新道具更新dom(如果它们相同则不更新)。

当然,将对话框的内容作为props参数传递并不是特别有用。我通常在下面扩展以解析markdown->
html的内容,或者在提供url作为道具时通过组件内部的ajax请求获取一些html。

我知道上面的代码并不完全是您想要的代码,但是我认为没有一种使React修改dom的插件有效的好方法。您永远不能假设react组件的dom表示是静态的,因此不能成功地由第三方插件操纵。老实说,我想如果您想以这种方式使用react,那么您应该重新评估使用框架的原因。

就是说,我认为上面的代码是对话框的一个很好的起点,在对话框中所有操作都在组件内部进行,这毕竟是reactjs的全部内容!

注意:代码是从内存中非常快速地编写的,并且没有以当前的形式进行实际测试,因此如果出现一些较小的语法错误或其他错误,请对不起。

2020-07-22