【问题标题】:How to fix "Cannot read property 'setState' of undefined" in React [duplicate]如何在 React [重复] 中修复“无法读取未定义的属性‘setState’”
【发布时间】:2019-06-24 16:59:35
【问题描述】:

我的应用从 Firebase 实时数据库中检索数据并尝试以“状态”加载它,但出现错误“无法读取属性 setState of undefined”。

我尝试在构造函数中添加绑定,但它不起作用

import React from 'react';

import { View } from '@vkontakte/vkui';

import * as firebase from "firebase/app";
import {config} from './dbinit' // import firebase config
import "firebase/database";


import Home from './panels/Home';



class App extends React.Component {
    constructor(props) {
        super(props);
        this.setState = this.setState.bind(this);
        this.state = {
            activePanel: 'home',
            db: null,
            loading: true,
        };
        console.log("init");
    }

    componentDidMount = () => {
        let ref = firebase
         .initializeApp(config)
         .database()
         .ref();

        ref.once("value").then(function onSuccess(res) {
            console.log("success", res.val())


            this.setState({db: res.val(), loading: false})
            // ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'


        });
    }

    go = (e) => {
        this.setState({activePanel: e.currentTarget.dataset.to})
    };


    render() {
        const { loading, db } = this.state;
        return loading ? (
            <div>loading...</div>
        ) : (
            <View activePanel={this.state.activePanel}>
                <div>loaded</div>
            </View>

        );
    }
}

export default App;

我希望setState 的工作正确,但实际上有错误Cannot read property 'setState' of undefined'

【问题讨论】:

  • 考虑阅读这个:freecodecamp.org/news/…
  • 这不是在自定义组件类方法中丢失this,而是由于回调function 而丢失上下文。一个快速的解决方法是将var appThis = this; 放在ref.once() 调用之前,然后在回调中使用appThis.setState(...);

标签: javascript reactjs


【解决方案1】:

你很快就在这里失去了上下文。使用的功能:

    ref.once("value").then(function onSuccess(res) {
        console.log("success", res.val())


        this.setState({db: res.val(), loading: false})
        // ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'


    });

像这样使用箭头函数:

ref.once("value").then((res) => {
    console.log("success", res.val())


    this.setState({db: res.val(), loading: false})
    // ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'


});

【讨论】:

    【解决方案2】:

    原因是因为您使用的是常规函数,它根据被调用者而不是词法范围动态绑定 this 关键字...因为此代码在严格模式下运行(因为它在一个类中)this关键字被解析为未定义。

    如果您希望保留上下文,则必须绑定函数或使用箭头函数(根据词法范围绑定 this 关键字)

    转换这个

    ref.once("value").then(function onSuccess(res) {
            console.log("success", res.val())
    
    
            this.setState({db: res.val(), loading: false})
            // ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'
    
    
    });
    

    到这里

    ref.once("value").then(res => this.setState({db: res.val(), loading: false}));
    

    【讨论】:

      【解决方案3】:

      从您对箭头函数的使用中,我看到您的 Babel 配置能够处理类字段的更新(即将发布)ES 功能,因此完全摆脱您的构造函数可能是值得的。

      class App extends React.Component {
          state = {
              activePanel: 'home',
              db: null,
              loading: true,
          };
      
          componentDidMount = () => {
          ....
      

      这并没有回答问题,但我想我会提到它:)

      Viktor 的回答提到您的“this”上下文因不使用箭头函数而丢失,这是正确的。

      【讨论】:

        猜你喜欢
        • 2019-08-27
        • 1970-01-01
        • 2018-09-11
        • 1970-01-01
        • 2018-10-06
        • 2017-07-09
        • 2019-04-09
        • 2018-12-05
        相关资源
        最近更新 更多