ComponentDidMount возвращает неопределенное значение после первоначального монтирования - PullRequest
0 голосов
/ 16 января 2019

Мой компонент правильно монтируется после однократного чтения из firebase, но он отказывает со второй попытки и говорит, что не может получить значение, потому что «привязка» не определена. Я новичок, чтобы реагировать, но я предполагаю, что что-то не хватает привязки?

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

1 Ответ

0 голосов
/ 16 января 2019

Ваша setInterval функция вызывает обработчик события, который вы передаете для события "value".

Это происходит потому, что метод Database#on возвращает обратный вызов , который вы передаете on (чтобы отменить регистрацию события позже во время фазы очистки).

Таким образом, когда setInterval вызывает ваш обратный вызов, он не сможет передать параметр snap, увидев, что он вызывает обратный вызов (а не экземпляр database) - это объясняет, почему snap undefined.

Также - я не уверен, для чего здесь служит 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 = '';
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...