我怎样才能使用这个'在defaultProps React.Component类语法中?

时间:2017-06-16 15:47:56

标签: javascript class reactjs ecmascript-6

在过去,我能够设置一个使用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道具允许我在MyButton组件中使用ref,但如果父组件需要访问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作为支柱来实现这一点......

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类语法吗?

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

所以我从我的HOC获得了addAddressSearch(component)功能。它添加了连接Google Places API所需的功能。但是要让谷歌的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>
        );
    }
}

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

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

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

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

似乎没有错误。

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

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

在defaultProp中,使用实例:

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