以编程方式反应集合组件道具

时间:2018-08-24 13:53:47

标签: javascript reactjs

我试图以某种方式动态地设置一个react(v15)组件的props回调函数。如下图所示,发芽它无法正常工作。

其背后的全部想法是,弹出窗口需要返回专门针对在网格(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} />

-

更新

我如何设法使其最终奏效。我使用状态来设置弹出窗口用于回调的函数。当您单击网格中的一个项目时:调用notificationsColumnsObj [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>);
    }
}

2 个答案:

答案 0 :(得分:2)

它不起作用有两个原因:

  1. 因为您的推荐人称为searchPopup,而不是props。对于the documentation for legacy string refs,您可以通过this.refs.searchProps进行访问。

  2. 因为props are read-only

我对第二条规则得到积极执行感到惊讶,但这是一件好事。 :-)

如果要更改子组件的道具,可以通过更改状态来进行,以便使用新道具重新渲染子组件。这是React Lifting State Up / Data Flows Down哲学的一部分。

答案 1 :(得分:0)

与其保留新的回调函数,不如保留一个函数,而是向其提供数据。

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)}/>
}
相关问题