【问题标题】:addComponentAsRefTo(...): Only a ReactOwner can have refs - Error in Form with Select ListaddComponentAsRefTo(...):只有 ReactOwner 可以拥有 refs - 选择列表的表单错误
【发布时间】:2017-06-25 11:04:55
【问题描述】:

我有一个在 React 中构建的选择列表,它工作正常,但我不断收到来自 React 的错误。我在缩小模式下遇到更多错误,这更糟。我已被定向到https://facebook.github.io/react/docs/error-decoder.html?invariant=119https://facebook.github.io/react/docs/error-decoder.html?invariant=120 的 Facebook 链接,但那里的任何选项都没有真正帮助我。

我查看了我引用的库,找不到 React 的重复加载(它是页面上加载的 CDN 并由 Browserify / Browserify-shim 外部化 - 我已经通过捆绑包寻找 React 代码并且没有找到它。)我通过在我的页面上注释掉 React 进行了仔细检查,并且一切都尽职尽责地失败了(如预期的那样),所以我认为它与我的代码有关。

根组件如下所示...

export default class Select extends React.Component {

    constructor(props) {
        super(props)

        this.state = { 
            value: this.props.value || ""
        }

        this.handleSelectChange = this.handleSelectChange.bind(this)
        this.clearValue = this.clearValue.bind(this)
    }

    handleSelectChange(e) {
        this.state.value = e.target.value
        this.props.onChange(e)
    }

    clearValue() {
        this.setState({ value: this.props.defaultValue })
        this.forceUpdate()
    }

    render() {
        const optionNodes = this.props.options.map((obj, index) => {
            return <ListItem
                key = {index.toString()}
                data = {obj}
                currentSelectedValue = {this.state.value} />
        })
        return (
            <select 
                className = "form-control drop-down" 
                id = {this.props.name}
                name = {this.props.name} 
                onChange = {this.handleSelectChange} 
                disabled = {this.props.disabled}
                value = {this.state.value}>
                {this.state.value == this.props.defaultValue && 
                    <option 
                        id = {`${this.props.name}-placeholder`} 
                        className = "placeholder" 
                        value = {this.props.defaultValue} disabled hidden>
                        {this.props.placeholder}
                    </option>}
                {optionNodes}
            </select>
        )
    }
}

这里被更高的组件使用...

export default class SelectFormLine extends React.Component {

    constructor(props) {
        super(props)

        this.clearValue = this.clearValue.bind(this)
    }

    clearValue() {
        this.refs.selectList.clearValue()
    }

    render() {
        return (
            <div className="row padded-row">
                <div className="drop-down-line form-group">
                    <FormLabel
                        name = {this.props.name}
                        className = {this.props.labelClassName} 
                        value = {this.props.label} />
                    <div className={this.props.inputClassName}>
                        <Select
                            name = {this.props.name} 
                            ref = "selectList"
                            placeholder = {this.props.placeholder}
                            onChange = {this.props.onChange}
                            value = {this.props.value}
                            defaultValue = {this.props.defaultValue}
                            disabled = {this.props.disabled}
                            options = {this.props.options} />
                        <FormInputNotes>{this.props.children}</FormInputNotes>
                    </div>
                </div>
            </div>
        )
    }
}

在我的表单中 (sn-p)...

导出默认类 UserManagementForm 扩展 React.Component {

constructor(props) {
    super(props)

    this.state = { 
        organisationsDisabled: true,
        typesLookupData: [],
        organisationsLookupData: []
    }

    this.handleTypeChange = this.handleTypeChange.bind(this)
}

handleTypeChange(e) {
    const changedUser = this.props.object
    changedUser.role = e.target.value
    this.refs.organisationIdSelect.clearValue()
    changedUser.organisationId = ""
    this.setState({ organisationsDisabled: false })
    this.props.onChange(changedUser)
    this.loadOrganisationsLookupData(changedUser.role)
}

render() {
    const labelClassNames = "col-md-2 col-sm-4"
    const inputClassNames = "col-md-10 col-sm-8"
    return (
        <InlineContent useFor = {this.props.useFor}>
            <Form.Wrapper
                formId = {this.props.formId}
                object = {this.props.object}
                className = "col-md-12"
                onSubmit = {this.props.onSubmit}
                onSubmitSuccess = {this.props.onSubmitSuccess}>
                {this.props.object.id !== undefined && <Form.Hidden name = "ID" value = {this.props.object.id} />}
                <Form.ErrorDisplay />
                {this.props.managed && this.props.useFor == "create" && <Form.SelectLine
                    name = "OrganisationId"
                    ref = "organisationIdSelect"
                    label = "Organisation"
                    labelClassName = {labelClassNames} 
                    inputClassName = {inputClassNames} 
                    placeholder = "Please select an organisation&hellip;"
                    onChange = {this.handleOrganisationChange}
                    value = {this.props.object.organisationId}
                    disabled = {this.state.organisationsDisabled}
                    options = {this.state.organisationsLookupData} /> }
                {!this.props.managed || this.props.useFor == "edit" && <Form.Hidden name = "OrganisationId" value = {this.props.object.organisationId} />}
                <Form.Buttons.SubmitCancel
                    className = {`${inputClassNames} col-md-offset-2 col-sm-offset-4`} 
                    submitText = {this.props.submitText} 
                    onCancel = {this.props.onCancel} />
            </Form.Wrapper>
        </InlineContent>
    )
}

}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    这个错误很奇怪。

    我只是将字符串引用更改为 Facebook 所说的开始使用的内容。 https://facebook.github.io/react/docs/refs-and-the-dom.html

    所以基本上你想做的事

    ref={(i) => this._whateverYouWantToCallIt = i}
    

    如果这不能解决问题,您的项目可能会有双重 React。

    【讨论】:

    • 像这样的东西让我希望我根本不用理会反应,而是使用纯 JS 和 jQuery 组件构建。
    • 太好了@jamby - 这解决了我的问题 - 我不得不将我的电话从 this.refs._whateverYouWantToCallIt 更改为 this._whateverYouWantToCallIt,但之后一切都很顺利。
    • @KeithJackson 你甚至不需要this.refs._whateverYouWantToCallIt。你可以做this._whateverYouWantToCallIt,它会起作用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2017-04-03
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多