ComponentDidMount 在初始挂载后返回 undefined

Posted

技术标签:

【中文标题】ComponentDidMount 在初始挂载后返回 undefined【英文标题】:ComponentDidMount returns undefined after initial mount 【发布时间】:2019-01-16 02:23:49 【问题描述】:

我的组件在从 firebase 读取一次后正确安装,但在第二次尝试时失败,并说它无法获取值,因为“snap”未定义。我是新手,但我认为缺少绑定?

import React,  Component  from "react";
import "./solar.css";
import firebase from "firebase";
import  config  from "../config";

let app = firebase.initializeApp(config);
let database = app
  .database()
  .ref()
  .child("values")
  .child("Voltage");

class Solar extends Component 
  state = 
    voltage: 0
  ;

  componentDidMount() 
    this.interval = setInterval(
      database.on("value", snap => 
        this.setState(
          voltage: snap.val()
        );
        console.log(snap.val());
      ),
      5000
    );
  

  componentWillUnmount() 
    clearInterval(this.interval);
  

【问题讨论】:

你为什么使用setInterval() 我希望组件每隔 5 秒更新一次 对 - 我已经提供了一个将setInterval 去掉的答案。要我重新插入吗? 【参考方案1】:

您的setInterval 函数正在调用您为"value" 事件传递的事件处理程序。

发生这种情况是因为您传递给 onDatabase#on 方法 returns the callback(以便稍后在清理阶段取消注册该事件)。

因此,当setInterval 调用您的回调时,它将无法传入snap 参数,因为它会调用回调(而是database 实例) - 这解释了为什么snapundefined

另外 - 我不确定 setInterval 在这里的用途。当在数据库中检测到值更改时,您似乎只希望组件更新(重新渲染)。在这种情况下,调用setState() 就足够了。

考虑修改您的代码如下:

import React, 
  Component
 from "react";
import "./solar.css";
import firebase from "firebase";
import 
  config
 from "../config";

let app = firebase.initializeApp(config);
let database = app
  .database()
  .ref()
  .child("values")
  .child("Voltage");

class Solar extends Component 
  state = 
    voltage: 0
  ;

  componentDidMount() 
  
    // Store reference to the "on value" callback for deregistering
    // the event when the Solar component unmounts
    this.valueChangeCallback = database.on("value", snap => 
      this.setState(
        voltage: snap.val()
      );
      console.log(snap.val());
    )
  

  componentWillUnmount() 
  
    // If a valueChangeCallback exists from former mount then deregister
    // this callback from you database instance
    if(this.valueChangeCallback) 
      database.on("value", this.valueChangeCallback);
      this.deregisterCallback = '';
    
  

【讨论】:

啊,谢谢。我已经回去修改了我的代码。这适用于此应用程序。我确实希望更新的速度比数据库更新的慢一点,但是有了这些信息,我能够正确地重新集成 setInterval,并且我知道如何正确设置它。 不客气 - 很高兴我能帮上忙。听起来是个有趣的项目 :-)

以上是关于ComponentDidMount 在初始挂载后返回 undefined的主要内容,如果未能解决你的问题,请参考以下文章

react的生命周期

React 组件的生命周期

react 的生命周期函数

react生命周期和组件生命周期

react请求接口数据是在componentDidMount 还是componentWillMount周期好

react的父子组件执行顺序