我试图将zurb揭示与形式整合到反应组件中.到目前为止,下一个代码正确显示模态形式:
ModalForm = React.createClass({ handleSubmit: function(attrs) { this.props.onSubmit(attrs); return false; }, render: function(){ return( ); } });
该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(); } });
问题:当我在模态表单组件中呈现表单组件并在表单输入中输入内容时,我会在控制台异常中看到Uncaught object
.这是一个堆栈:
Uncaught object invariant ReactMount.findComponentRoot ReactMount.findReactNodeByID getNode ...
如果我只是直接在父组件中渲染表单组件,那么一切正常.有人可以帮忙吗?
简而言之,你做错了,这不是反应中的错误.
如果您使用任何类型的插件来修改react组件的dom节点,那么它将以某种方式破坏事物.
你应该做的是使用react本身和补充css来按照你想要的模态对话的方式定位组件.
我建议创建一个组件,它使用react的statics
组件属性来定义一些函数包装renderComponent
,为您提供一个很好的干净函数调用来显示或隐藏反应对话框.这是我过去使用过的一个减少的例子.注意:它确实使用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作为prop时通过组件内部的ajax请求获取一些html.
我知道上面的代码并不完全是你想要的,但我认为有一个很好的方法可以使dom修改插件与react一起工作.你永远不能假设react组件的dom表示是静态的,因此它不能被第三方插件成功操作.老实说,如果你想以这种方式使用反应,你应该重新评估你使用框架的原因.
也就是说,我认为上面的代码是一个对话框的一个很好的起点,在这个对话框中,所有操作都发生在组件内部,而这反过来就是reactjs的全部内容!
注意:代码是从内存中快速编写的,并没有实际测试它的当前形式,所以很抱歉,如果有一些小的语法错误或其他东西.
以下是迈克所做的事情,但使用zf揭示模态:
var Dialog = React.createClass({ statics: { open: function(){ this.$dialog = $('#my-dialog'); if (!this.$dialog.length) { this.$dialog = $('<div id="my-dialog" class="reveal-modal" data-reveal role="dialog"></div>') .appendTo('body'); } this.$dialog.foundation('reveal', 'open'); return React.render( <Dialog close={this.close.bind(this)}/>, this.$dialog[0] ); }, close: function(){ if(!this.$dialog || !this.$dialog.length) { return; } React.unmountComponentAtNode(this.$dialog[0]); this.$dialog.foundation('reveal', 'close'); }, }, render : function() { return ( <div> <h1>This gets rendered into the modal</h1> <a href="#" className="button" onClick={this.props.close}>Close</a> </div> ); } });