【问题标题】:Why this.state is undefined in react native?为什么 this.state 在本机反应中未定义?
【发布时间】:2017-08-21 20:01:14
【问题描述】:

我是 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 = () =&gt; {}toggle = () =&gt; {}

但是在 JS 中它不起作用:(

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    第一个示例中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 可能会有所帮助。

    【讨论】:

    • 这篇文章正是我需要了解的内容。唯一的问题是每个组件实例化创建一次?
    • 我的意思是,我真的很喜欢这种属性语法,但它会影响性能吗?
    • @NickKraev 取决于。如果页面上没有数百个组件,则没有任何意义。一般来说 JS 相当快,还有许多其他的 React 优化会比这更有影响力(例如,shouldComponentUpdate-type 的东西)。
    • 很好的解释,仍然需要弄清楚很多。谢谢!
    【解决方案2】:

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

    进一步阅读 -

    ES6 Arrow Functions

    .bind()

    【讨论】:

    • 一般你不想在render期间创建新函数。而是在ctor中绑定或使用自动绑定的实例属性函数。
    • 是的,很好。如果您在渲染中使用箭头函数,它每次都会创建一个新函数。我认为即使是 React 文档也推荐 .bind()
    【解决方案3】:

    第一个示例中发生的情况是您失去了“this”的范围。通常我所做的是在构造函数中定义我的所有函数,如下所示:

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

    在第二个示例中,您使用的是 ES6 语法,它会自动绑定 this(这就是它起作用的原因)。

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

    onPress={this.toggle}
    

    【讨论】:

    • 我想你会想要this.toggle,否则它会在渲染时被执行。
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2018-11-20
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    相关资源
    最近更新 更多