繁体   English   中英

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

[英]How can I use 'this' in defaultProps React.Component class syntax?

在过去,我能够设置一个使用this的默认道具......

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 prop允许我在MyButton组件中使用ref,但如果父组件需要访问MyButton DOM节点,也始终能够传入自定义ref。

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作为支柱来实现...

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

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

编辑:显然我的简化示例没有充分说明这一点,所以我可以提出一个更实际的例子,或者你们都可以回答原来的问题:我需要做什么才能在我的defaultProps使用this 我可以不再使用JS类语法吗?

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

所以我从我的HOC获得了addAddressSearch(component)函数。 它添加了连接Google Places 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 ,我只需传递一个inputRef prop的AddressSearchInput

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>
        );
    }
}

也许这种方式是错综复杂的错误,但我没有时间找出另一种方法来自己做。 所以要么指向一个关于最好的方法来加入第三方API并添加动态表单验证而不使用refs或回答我的原始问题的教程...

我需要做什么才能在defaultProps使用this 我可以不再使用JS类语法吗?

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

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

这似乎没有错误地工作。

无论如何,最初的问题仍然存在。 我需要做什么才能在defaultProps使用this 我可以不再使用JS类语法吗?

如果要对该按钮进行引用,请在类级别绑定变量并将其分配给该类变量。 例:

export default class MyComponent extends Component {
  componentDidMount() {
    // button will be available as `this.button`
  }

  button = null;  // initialize to null

  render() {
    return (
      <div>
        <Button ref={e => { this.button = e; }} />
      </div>
    );
  }
}

这真的应该是一种方法,而不是财产。

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>
        );
    }
}

由于静态属性不了解类实例,如果必须使静态方法知道给定实例,唯一的方法是将实例作为参数传递给静态方法:

<button
    ref={(ref) => this.button = this.props.buttonRef(this, ref)}
    onClick={this.props.handleClick}
>

在defaultProp中,使用实例:

static defaultProps = {
    buttonRef: (instance, ref) => instance.button = ref
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM