我遵循这个指南使用DOM库,如jquery UI和reactJS。我最后用下面的代码来测试当我改变对话框的一个道具时会发生什么,在本例中是标题。
var Dialog = React.createClass({
render: function() {
return React.DOM.div();
},
componentDidMount: function() {
this.node = this.getDOMNode();
this.dialog = $(this.node).dialog({
title: this.props.title
}).data('ui-dialog');
this.renderDialogContent(this.props);
},
componentWillReceiveProps: function(newProps) {
this.renderDialogContent(newProps);
},
renderDialogContent: function(props) {
React.render(React.DOM.div({}, props.children), this.node);
if (props.open)
this.dialog.open();
else
this.dialog.close();
},
componentWillUnmount: function() {
this.dialog.destroy();
},
});
var MyApp = React.createClass({
render: function() {
return <Dialog title={"Dialog - " + (new Date().getTime()) - this.props.start} open={true}>
<h2>This is my dialog content!!!</h2>
</Dialog>
}
});
$(document).ready(function()
{
var start = new Date().getTime();
setInterval(function() {
React.render(
<MyApp startTime={start}/>,
document.getElementById('container')
);
}, 1000);
});
对话框弹出,但每次间隔滴答,另一个对话框被创建。对话框的componentDidMount函数每秒被调用一次。我做错什么了吗?
一般来说,你不应该在组件内部调用React.render
。每次间隔滴答,你正在卸载和重新安装对话框,触发componentDidMount
。每次发生这种情况,它都会初始化并打开对话框,导致您看到的行为。
我将startTime
道具移动到MyApp
状态,然后在MyApp
的componentDidMount
事件中设置间隔函数。interval函数应该调用setState
而不是React.render
。这将导致新的时间流向Dialog
组件,该组件可以使用componentWillReceiveProps
事件来更新对话框的title
选项,而无需重新初始化jQuery。
我还建议删除Dialog
组件上的open
道具,并让React处理卸载过程。您可以根据状态决定是否在MyApp
中呈现Dialog
组件。
像这样:
var Dialog = React.createClass({
render: function() {
return <div>
{this.props.children}
</div>;
},
componentDidMount: function() {
var dialog = $(this.getDOMNode()).dialog({
title: this.props.title
}).data('ui-dialog');
},
componentWillReceiveProps: function (newProps) {
$(this.getDOMNode()).dialog('option', 'title', newProps.title);
},
componentWillUnmount: function() {
$(this.getDOMNode()).dialog('destroy');
}
});
var dialogInterval;
var MyApp = React.createClass({
getInitialState: function() {
return {
openDialog: false,
time: new Date().getTime()
};
},
handleDialogToggleClick: function () {
this.setState({openDialog: !this.state.openDialog});
},
render: function() {
var dialog;
if (this.state.openDialog) {
dialog = <Dialog title={"Dialog - " + this.state.time}>
<h2>This is my dialog content!!!</h2>
</Dialog>;
}
return <div>
<button onClick={this.handleDialogToggleClick}>
Toggle the dialog
</button>
{dialog}
</div>;
},
componentDidMount: function () {
dialogInterval = setInterval(function() {
this.setState({time: new Date().getTime()});
}, 1000);
},
componentWillUnmount: function () {
dialogInterval = null;
}
});
$(document).ready(function() {
React.render(
<MyApp />,
document.getElementById('container')
);
});
我还没有测试过,但它应该给你一个我在说什么的想法。