我试图以某种方式动态地设置一个react(v15)组件的道具回调函数。像下面这样的东西,萌芽它不起作用,因为我想要它。
这背后的整个想法是弹出窗口需要返回特定在网格中按下的网格项的特定数据(html表)。
有关如何存档组件及其道具的动态设置的任何建议吗?
下面的代码给出了这个错误:
TypeError: can't define property "dynamicCallback": Object is not extensible
(我想元素道具是用Object.preventExtensions设置的)
getGridColumnData() {
var notificationsColumnsObj = columns.GridData; // from json file, Array With columns
for (let iColumn = 0; iColumn < notificationsColumnsObj.length; iColumn++) {
if (notificationsColumnsObj[iColumn].field === 'Landlord_Name') {
notificationsColumnsObj[iColumn]['editor'] = function (container, options) {
that.refs.searchCompanyPopup.props.dynamicCallback = function (data) {
var landlordName = null;
var landlordCode = null;
if (data) {
landlordCode = data.Code;
landlordName = data.Name;
}
options.model.set('Landlord_Code', landlordCode);
options.model.set('Landlord_Name', landlordCode);
};
};
}
}
return notificationsColumnsObj;
}
<SearchPopup ref="searchPopup" data={this.state.data} />
-
更新
我是如何设法将它最终工作的。我使用状态来设置弹出窗口用于回调的函数。当您单击网格中的项目时:callsColumnsObj [iColumn] ['editor']被调用,然后在完成调用该函数时为弹出回调设置状态。
var that;
class TheComponent extends React.Component {
constructor(props,context) {
super(props,context);
this.state={
data: {},
landlordSelectedCallback: function (data) {},
}
that = this;
}
getGridColumnData() {
var notificationsColumnsObj = columns.GridData; // from json file, Array With columns
for (let iColumn = 0; iColumn < notificationsColumnsObj.length; iColumn++) {
//only one item will match this, not multiple
if (notificationsColumnsObj[iColumn].field === 'Landlord_Name') {
notificationsColumnsObj[iColumn]['editor'] = function (container, options) {
that.setState({
landlordSelectedCallback: function (data) {
var landlordName = null;
var landlordCode = null;
if (data) {
landlordCode = data.Code;
landlordName = data.Name;
}
options.model.set('Landlord_Code', landlordCode);
options.model.set('Landlord_Name', landlordCode);
}
}, () => { //callback function, after the state is set
$(ReactDOM.findDOMNode(that.refs.searchPopup)).modal(); //shows the <SearchPopup modal
$(ReactDOM.findDOMNode(that.refs.searchPopup)).off('hide.bs.modal');
$(ReactDOM.findDOMNode(that.refs.searchPopup)).on('hide.bs.modal', function (e) {
$(ReactDOM.findDOMNode(that.refs.searchPopup)).off('hide.bs.modal');
that.closeGridCellFromEditing(); //closes the grid cell edit mode
});
});
};
}
}
return notificationsColumnsObj;
}
render() {
return (<div>[other nodes]
<SearchPopup ref="searchPopup" data={this.state.data} onModalFinished={this.state.landlordSelectedCallback} />
</div>);
}
}
这有两个原因:
searchPopup
,而不是props
。根据the documentation for legacy string refs
,你可以通过this.refs.searchProps
访问它。第二条规则是积极执行的,我有点惊讶,但那是件好事。 :-)
如果要更改子组件的道具,可以通过更改状态来实现,以便使用新道具重新渲染子项。这是React的Lifting State Up / Data Flows Down哲学的一部分。
而不是提供新的回调函数,只需保留一个函数,但向其提供数据。
getGridColumnData() {
var notificationsColumnsObj = columns.GridData; //from json file, Array With columns
for (let iColumn = 0; iColumn < notificationsColumnsObj.length; iColumn++) {
if (notificationsColumnsObj[iColumn].field === 'Landlord_Name') {
notificationsColumnsObj[iColumn]['editor'] = (function (container, options) {
this.options = options
}).bind(this);
}
}
return notificationsColumnsObj;
}
dynamicCallback = function (data) {
var landlordName = null;
var landlordCode = null;
if (data) {
landlordCode = data.Code;
landlordName = data.Name;
}
this.options.model.set('Landlord_Code', landlordCode);
this.options.model.set('Landlord_Name', landlordCode);
}
render() {
return <SearchPopup ref="searchPopup" data={this.state.data} dynamicCallback = {this.dynamicCallback.bind(this)}/>
}