如何让 react.js 和 zurb 一起发挥很好的显示模态形式 [英] How to make react.js play nice together with zurb reveal modal form

查看:53
本文介绍了如何让 react.js 和 zurb 一起发挥很好的显示模态形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 zurb 显示与表单集成到反应组件中.到目前为止,下一个代码正确显示模态形式:

ModalForm = React.createClass({句柄提交:函数(属性){this.props.onSubmit(attrs);返回假;},渲染:函数(){返回(<div><a href="#" data-reveal-id="formModal" className="button">新增</a><div id="formModal" className="reveal-modal" data-reveal><h4>添加新内容</h4><Form onSubmit={this.handleSubmit}/><a className="close-reveal-modal">&#215;</a>

);}});

Form 组件非常标准:

Form = React.createClass({句柄提交:函数(){var body = this.refs.body.getDOMNode().value.trim();如果(!身体){返回假;}this.props.onSubmit({body: body});this.refs.body.getDOMNode().value = '';返回假;},渲染:函数(){返回(<form onSubmit={this.handleSubmit}><textarea name="body" placeholder="说点什么..." ref="body"/><input type="submit" value="Send" className="button"/></表单>);}});

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

未捕获的对象不变的ReactMount.findComponentRootReactMount.findReactNodeByID获取节点...

如果我直接在父组件中渲染表单组件,那么一切正常.有人可以帮忙吗?

解决方案

简而言之,你做错了,这不是反应中的错误.

如果您使用任何类型的插件来修改 react 组件的 dom 节点,那么它就会以一种或另一种方式破坏事物.

您应该做的是使用 react 本身和互补的 css,以您希望的模式对话框的方式定位组件.

我建议创建一个组件,该组件使用 react 的 statics 组件属性来定义几个包装 renderComponent 的函数,以便为您提供一个漂亮干净的函数调用来显示或隐藏反应对话框.这是我过去使用过的东西的简化示例.注意:它确实使用了 jQuery,但是如果你不想要 jQuery 代码,你可以用标准的 js api 调用来替换 jQ,比如 elementById 等.

window.MyDialog = React.createClass({道具类型:{标题:React.PropTypes.string.isRequired,内容:React.PropTypes.string.isRequired},静态:{//打开一个以 props 对象作为 props 的对话框打开:功能(道具){var $anchor = $('#dialog-anchor');如果 (!$anchor.length) {$anchor = $('<div></div>').prop('id', '对话框锚');.appendTo('body');}返回 React.renderComponent(我的对话框(道具),$anchor.get(0));},//关闭对话框关闭:函数(){React.unmountComponentAtNode($('#dialog-anchor').get(0));}},//当对话框打开时,向 body 添加一个 keyup 事件处理程序componentDidMount:函数(){$('body').on('keyup.myDialog', this.globalKeyupHandler);},//当对话框关闭时,清除 body 上绑定的 keyup 事件处理程序componentWillUnmount:函数(){$('body').off('keyup.myDialog');},//处理 body 上的 keyup 事件globalKeyupHandler:函数(e){if (e.keyCode == 27) {//ESC 键//关闭对话框this.statics.close();}},//非常基本的对话框 dom 布局 - 使用您自己的渲染:函数(){<div className="对话框"><div className="title-bar"><div className="title">{this.props.title}</div><a href="#" className="close" onClick={this.closeHandler}>

<div className="内容">{this.props.content}

}});

然后您通过调用打开一个对话框:

MyDialog.open({title: '对话框标题', content: '我的对话框内容'});

并用

关闭它

MyDialog.close()

对话框总是附加到一个新的 dom 节点,直接在 body 下,id 为 'dialog-anchor'.如果你在一个对话框已经打开的情况下打开一个对话框,它只会根据新的 props 更新 dom(或者如果它们相同,则不会更新).

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

我知道上面的代码并不是你要找的,但我认为没有什么好方法可以让 dom 修改插件与 react 一起工作.你永远不能假设 react 组件的 dom 表示是静态的,因此它不能被 3rd 方插件成功操纵.老实说,我认为如果您想以这种方式使用 react,您应该重新评估您使用该框架的原因.

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

注意:代码是从内存中快速编写的,并没有以当前的形式进行实际测试,如果有一些小的语法错误或其他问题,请见谅.

I am trying to integrate zurb reveal with form into react component. So far next code properly displays modal form:

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>
    );
  }
});

The Form component is pretty standard:

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>
    );
  }
}); 

Problem: When I render form component within modal form component and enter something into form input then I see in console exception Uncaught object. This is a stack:

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

If I just render form component directly in the parent component then everything works. Could anybody help please?

解决方案

In short, you're doing this wrong and this is not a bug in react.

If you use any kind of plugin that modifies the react component's dom nodes then it's going to break things in one way or another.

What you should be doing instead is using react itself, and complementary css, to position the component in the way you'd like for your modal dialog.

I would suggest creating a component that uses react's statics component property to define a couple of functions wrapping renderComponent to give you a nice clean function call to show or hide a react dialog. Here's a cut down example of something I've used in the past. NB: It does use jQuery but you could replace the jQ with standard js api calls to things like elementById and etc if you don't want the jQuery code.

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>
    }
});

You then open a dialog by calling:

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

And close it with

MyDialog.close()

The dialog always attaches to a new dom node directly under body with id 'dialog-anchor'. If you open a dialog when one is already open, it will simply update the dom based on new props (or not if they're the same).

Of course passing the content of the dialog as a props argument isn't particularly useful. I usually extend below to either parse markdown -> html for the content or get some html via an ajax request inside the component when supplying a url as a prop instead.

I know the above code isn't exactly what you were looking for but I don't think there's a good way to make a dom-modifying plugin work with react. You can never assume that the dom representation of the react component is static and therefore it can't be manipulated by a 3rd party plugin successfully. I honestly think if you want to use react in this way you should re-evaluate why you're using the framework.

That said, I think the code above is a great starting point for a dialog in which all manipulation occurs inside the component, which afterall is what reactjs is all about!

NB: code was written very quickly from memory and not actually tested in it's current form so sorry if there are some minor syntax errors or something.

这篇关于如何让 react.js 和 zurb 一起发挥很好的显示模态形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆