javascript - 如何在 defaultProps React.Component 类语法中使用 'this' ?

标签 javascript class reactjs ecmascript-6

过去我能够设置一个使用 this 的默认 prop,如下所示...

let MyButton = React.createClass({
    getDefaultProps() {
        return {
            buttonRef: (ref) => this.button = ref
        };
    },

但是现在我使用 JS 类 MyButton 看起来像这样......

class MyButton extends React.Component {
    static defaultProps = {
        buttonRef: (ref) => this.button = ref
    };

我收到一条错误消息,指出 this 未定义。

我需要做什么才能设置使用 this 的默认属性?

编辑:添加一些上下文

设置默认的 buttonRef 属性允许我使用 MyButton 组件中的引用,但如果父组件需要访问 MyButton DOM 节点,也始终能够传入自定义引用。

class MyButton extends React.Component {
    static defaultProps = {
        buttonRef: (ref) => this.button = ref
    };

    componentDidMount() {
        Ladda.bind(this.button);
    }

    render() {
        return (
            <button
                ref={(ref) => this.button = this.props.buttonRef(ref)}
                onClick={this.props.handleClick}
            >
                {this.props.buttonText}
            </button>
        );
    }
}

所以我的按钮总是可以挂接到Ladda:Ladda.bind(this.button)

如果我需要在父组件中访问该按钮的 DOM 节点,我可以通过传入 buttonRef 作为 prop 来实现,例如...

class MouseOverButton extends React.Component {
    componentDidMount() {
        this.mouseEnterButton.addEventListener("mouseover", doSomething(event));
    }

    render() {
        return (
            <div>
                <MyButton
                    buttonRef={(ref) => this.mouseEnterButton = ref}
                />
            </div>
        );
    }
}

编辑:显然我的简化示例并不能很好地说明这一点,因此我可以提出一个更实际的示例,或者你们可以回答原来的问题:我需要做什么才能使用 this在我的 defaultProps 中?我可以不再使用 JS 类语法来做到这一点吗?

当使用将嵌套组件挂接到某些第三方 API 的 HOC 时,为特定元素的 ref 指定 defaultProp 的约定非常有用。我有一个 AddressSearch HOC,它通过传递给包装组件的函数获取一个节点。然后它使用该节点将其与 Google 的 Places API 连接起来。

所以我从我的 HOC 中得到了 addAddressSearch(component) 函数。它添加了连接 Google 地点 API 所需的功能。但为了让 Google 的 API 正常工作,我需要知道我正在使用哪个 DOM 节点。因此,我向 Input 组件传递了一个 inputRef,它使我的 AddressSearchInput 能够访问适当的节点。

class AddressSearchInput extends React.Component {
    static defaultProps = {
        inputRef: (ref) => this.addressSearchInput = ref
    };

    componentDidMount() {
        let node = this.addressSearchInput;

        this.props.mountAddressSearch(node);
    }

    render() {
        return (
            <div>
                <Input
                    inputAttributes={inputAttributes}
                    inputRef={(ref) => this.addressSearchInput = this.props.inputRef(ref)}
                    labelText={<span>Event address or venue name</span>}
                    labelClassName={labelClassName}
                />
            </div>
        );
    }
}

AddressSearchInput = addAddressSearch(AddressSearchInput);

module.exports = AddressSearchInput;

// Here's the Input component if that helps complete the picture here
class Input extends React.Component {
    render() {
        return (
            <div>
                <Label>{this.props.labelText}</Label>
                <HelperText text={this.props.inputHelperText} />
                <input
                    {...this.props.inputAttributes}
                    ref={this.props.inputRef}
                ></input>
            </div>
        );
    }
}

现在,当我想在需要向相关节点添加 eventListener 的父组件中使用 AddressSearchInput 时,我只需向 AddressSearchInput 传递 inputRef 属性即可。

class VenueStreetAddress extends React.Component {
    componentDidMount() {
        let node = this.venueStreetAddressInput;
        this.props.mountValidateOnBlur(node, venueValidationsArray);
    },
    render() {
        return (
            <div>
                <AddressSearchInput
                    inputRef={(ref) => this.venueStreetAddressInput = ref}
                    hasError={this.props.hasError}
                />
                {this.props.errorMessageComponent}
            </div>
        );
    }
}

我可以在任何地方使用 AddressSearchInput 并且不会破坏任何东西。

class UserStreetAddress extends React.Component {
    componentDidMount() {
        let node = this.userStreetAddressInput;
        this.props.mountValidateOnBlur(node, userValidationsArray);
    },
    render() {
        return (
            <div>
                <AddressSearchInput
                    inputRef={(ref) => this.userStreetAddressInput = ref}
                    hasError={this.props.hasError}
                />
                {this.props.errorMessageComponent}
            </div>
        );
    }
}

也许这种方式很复杂而且错误,但我没有时间自己找出另一种方法。因此,要么向我提供有关连接第 3 方 API 并在不使用引用的情况下添加动态表单验证的最佳方法的教程,要么回答我原来的问题...

我需要做什么才能在我的 this 中使用 defaultProps ?我可以不再使用 JS 类语法来做到这一点吗?

编辑:在尝试解释我的用例时,我想到让我的 defaultProps 看起来像这样......

static defaultProps = {
    inputRef: (ref) => ref
};

这似乎工作正常,没有错误。

无论如何,原来的问题仍然存在。 我需要做什么才能在我的 this 中使用 defaultProps ?我可以不再使用 JS 类语法来做到这一点吗?

最佳答案

这确实应该是一个方法,而不是一个属性。

class MyButton extends React.Component {
    setButtonRef (ref) {
        this.button = ref;
    }
    componentDidMount() {
        Ladda.bind(this.button);
    }
    render() {
        return (
            <button
                ref={ ref => this.setButtonRef(ref) }
                onClick={this.props.handleClick}
            >
                {this.props.buttonText}
            </button>
        );
    }
}

关于javascript - 如何在 defaultProps React.Component 类语法中使用 'this' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44593273/

相关文章:

c# - Aspx页面中的foreach循环如何添加复选框和标签

javascript - 检查是否使用 jQuery/JavaScript 将特定对象加载到 DOM 中?

python - 使用 SQLAlchemy 基于类自动构建数据库表

c++ - 引用类型的数据成员提供 "loophole"围绕 const 正确性

javascript - 如何从另一个模块中的异步函数获取 Promise 返回对象

javascript - 从任意 Angular html Canvas 复制一个矩形

javascript - 通过用户脚本读取 websocket 通信

javascript - React + Redux 绑定(bind)状态没有数据

javascript - React 嵌套模块显示 "Uncaught ReferenceError: Nav is not defined"

javascript - 当我使用经典的 asp、jquery 和 ajax 从第一个下拉列表中选择一个值时,如何显示所选项目的表格?