我看了很多其他类似的问题,但大多数都是不同的。那些类似的东西并没有解决我的问题。所以就这样了。
我在React中有两个组件,其中一个父组件将它们呈现为一个div。其中一个组件有一个按钮和一个模态形式。另一个是DataTable,其中包含编辑和删除行的选项。当我更新或删除表组件中的行并更新表内容时,一切正常。我可以看到删除了一行,或者更改了值。但是当我尝试对其他组件做同样的事情时,我得到一个错误。
我的表组件呈现以下内容:
var DiaryDataTable = React.createClass({
getDefaultProps() {
return {
tableData: []
};
},
getInitialState() {
return {
diaryLogs: []
};
},
editLog(diaryLogId, parameterId, value) {
alert('edit log: ' + diaryLogId + ', ' + parameterId + ', ' + value);
},
deleteLog(diaryLogId) {
var self = this;
if(!confirm('Delete diary log?')) {
return;
}
var url = "{{ url('diary/') }}/" + diaryLogId;
$.ajax({
url: url,
type: 'DELETE',
success: function(response) {
if(response.data.result) {
showNotificationPopup('success', 'Diary log deleted successfully!');
refreshTable();
} else {
showNotificationPopup('danger', 'Error deleting diary log!');
}
},
error: function(response) {
handleAjaxError(response);
}
});
},
getDiaryLogs() {
var self = this;
$.ajax({
url: "{{ url('api/diary/' . \Auth::user()['id']) }}",
type: 'GET',
success: function(response) {
var data = response.data.diary_logs;
self.setState({ diaryLogs: data });
self.forceUpdate();
},
error: function(response) {
handleAjaxError(response);
}
});
},
componentDidUpdate() {
$('#diary_table').DataTable();
},
componentDidMount() {
var self = this;
window.refreshTable = function() {
console.log('refreshing table');
self.getDiaryLogs();
}
refreshTable();
},
render() {
var self = this;
var tableBody = this.state.diaryLogs.map(function(d, index){
return (
<tr>
<td>{d.date}</td>
<td>{d.parameter_name}</td>
<td>{d.value}</td>
<td>
<a href="#" onClick={ self.editLog.bind(self, d.id, d.parameter_id, d.value) }>Edit</a> |
<a href="#" onClick={ self.deleteLog.bind(self, d.id) }> Delete</a>
</td>
</tr>
);
});
return (
<table id="diary_table" className="table table-bordered table-striped">
<thead>
<th>Date</th>
<th>Parameter</th>
<th>Value</th>
<th>Actions</th>
</thead>
<tbody>
{ tableBody }
</tbody>
</table>
);
}
});
var AddParameterModalForm = React.createClass({
getDefaultProps() {
return {
editForm: 0
};
},
getInitialState: function () {
var modalTitle = 'Add Diary Log';
if(this.props.editForm == 1) {
modalTitle = 'Edit Diary Log';
}
return {
showModal: false,
modalTitle: modalTitle,
parameterId: 0,
value: '',
parameterList: [],
date: ''
};
},
close: function () {
$('#add_parameter_modal').modal('hide');
},
show: function () {
$('#add_parameter_modal').modal('show');
},
updateParameterId(e) {
this.setState({parameterId: e.target.value});
},
updateValue(e) {
this.setState({value: e.target.value});
},
updateDate(e) {
this.setState({date: e.target.value});
},
getUserParameters() {
var self = this;
var url = "{{ url('api/parameters?user_id=' . \Auth::user()['id']) }}";
$.ajax({
url: url,
type: 'GET',
success: function(response) {
self.setState({ parameterId: response.data.parameters[0]['id'] });
self.setState({ parameterList: response.data.parameters });
},
error: function(response) {
handleAjaxError(response);
}
});
},
componentDidMount() {
this.getUserParameters();
},
saveLog(e) {
var self = this;
e.preventDefault();
var data = {
date: this.state.date,
parameter_id: this.state.parameterId,
value: this.state.value
};
$.ajax({
url: '{{ url("diary") }}',
type: 'POST',
data: JSON.stringify(data),
success: function(response) {
if(response.data.result) {
showNotificationPopup('success', 'Diary log saved successfully!');
self.close();
/*****************************************************/
This call to refreshTable() breaks and causes the error
/*****************************************************/
refreshTable();
} else {
showNotificationPopup('danger', 'Error saving diary log!');
}
},
error: function(response) {
handleAjaxError(response);
}
});
},
render() {
var parametersList = [];
$.each(this.state.parameterList, function(idx, val) {
parametersList[val.id] = val.parameter_name;
});
drawDropDown('#parameter_drop_down', parametersList);
var buttonStyle = {
marginLeft: '20px'
};
return (
<div>
<div className="box-header">
<h3 className="box-title">Diary</h3>
<button style={ buttonStyle } onClick={ this.show } className="btn btn-primary">Add Log</button>
</div>
<div className="modal" id="add_parameter_modal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 className="modal-title">{ this.state.modalTitle }</h4>
</div>
<div className="modal-body">
<form onSubmit={ this.saveLog }>
<div className="box-body">
<div className="form-group">
<label>Date</label>
<input type="date" className="form-control"
placeholder="Parameter Value"
onChange={ this.updateDate }
value={ this.state.date }
required />
</div>
<div className="form-group">
<label>Parameter</label>
<select className="form-control select2"
id="parameter_drop_down"
onChange={ this.updateParameterId }
value={ this.state.parameterId }
required >
</select>
</div>
<div className="form-group">
<label>Value</label>
<input type="text" className="form-control"
onChange={ this.updateValue }
placeholder="Value"
value={ this.state.value }
required />
</div>
<div className="box-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" id="save_parameter_button" className="btn btn-primary">Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
});
var DiaryLogModule = React.createClass({
render() {
return (
<div className="box">
<AddParameterModalForm />
<div className="box-body">
<DiaryDataTable />
</div>
</div>
);
}
});
这很好用。
从另一个组件中,一旦我使用模态表单添加一个新行,我就调用了一个在
中的函数表组件的componentDidMount()
。这基本上用新值设置表模态的状态,再次调用渲染函数(这就是我上面提到的)。发生这种情况时,我收到以下错误:
未捕获错误:不变违规:findComponentRoot(..., .0.1.0.1.2.0):无法找到元素。这可能意味着DOM是 意外地突变(例如,通过浏览器),通常是由于遗忘 a使用表格时,嵌套
或标签,或使用非SVG 父母中的元素。尝试检查。的子节点 具有反应ID的元素``。
我距离React只有两天。大多数帖子说这应该有效。这里的任何建议都表示赞赏。