为什么this.state在native native中是未定义的?

时间:2017-03-28 16:16:36

标签: javascript reactjs react-native

我是反应原生,react.js和javascript的完整新手。我是Android开发人员,所以想试试RN。

基本上,区别在于onPress;

此代码在toggle()运行时显示'undefined'

class LoaderBtn extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: false };
    }

    toggle() {
        console.log(this.state);
        // let state = this.state.loading;
        console.log("Clicked!")
        // this.setState({ loading: !state })
    }

    render() {
        return (
            <Button style={{ backgroundColor: '#468938' }} onPress={this.toggle}>
                <Text>{this.props.text}</Text>
            </Button>
        );
    }
}

但是此代码有效:

class LoaderBtn extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: false };
    }

    toggle() {
        console.log(this.state);
        // let state = this.state.loading;
        console.log("Clicked!")
        // this.setState({ loading: !state })
    }

    render() {
        return (
            <Button style={{ backgroundColor: '#468938' }} onPress={() => {this.toggle()}}>
                <Text>{this.props.text}</Text>
            </Button>
        );
    }
}
你能解释一下这个区别吗?

在Java / Kotlin中,我们有方法引用,如果签名相同,基本上它会传递函数,例如onPress = () => {}toggle = () => {}

但在JS中它不起作用:(

3 个答案:

答案 0 :(得分:24)

第一个示例toggle()中的问题未绑定到正确的this

你可以在ctor中绑定它:

constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    ...

或者使用实例函数(在某些情况下可以):

toggle = () => {
    ...
}

此方法需要通过stage-2transform-class-properties进行构建更改。

使用实例属性函数的警告是每个组件创建一个函数。如果页面上没有很多,这是可以的,但要记住这一点。一些模拟库也没有特别好地处理箭头函数(即箭头函数不在原型上,而是在实例上)。

这是基本的JS; this article regarding React Binding Patterns可能有帮助。

答案 1 :(得分:5)

我认为正在发生的事情是范围问题。当您使用onPress={this.toggle}时,这不是您在切换功能中所期望的。但是,箭头函数表现出不同的行为并自动绑定到this。您也可以使用onPress={this.toggle.bind(this)}

进一步阅读 -

ES6 Arrow Functions

.bind()

答案 2 :(得分:4)

第一个例子中发生的事情是你已经失去了&#34;这个&#34;的范围。通常我所做的是在构造函数中定义我的所有函数,如下所示:

constructor(props) {
    super(props);
    this.state = { loading: false };
    this.toggle = this.toggle.bind(this);
}

在第二个示例中,您使用的是ES6语法,它将自动绑定它(这就是为什么会这样做)。

然后在你的onPress函数里面,你需要调用你构建的函数。所以它看起来像这样,

onPress={this.toggle}