Ваша функция 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 = '';
}
}
}
Прежде, чем задать этот вопрос я посмотрел на часть исходного кода MVC, но очевидно я пропустил это, которое является, как они делают это для помощника Изображения.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(imageRelativeUrl)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
}
UrlHelper url = new UrlHelper(helper.ViewContext);
string imageUrl = url.Content(imageRelativeUrl);
return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
}
Похож на инстанцирование нового UrlHelper
корректный подход, в конце концов. Это достаточно хорошо для меня.
Обновление: код RTM от исходного кода ASP.NET MVC v1.0 немного отличается, как указано в комментариях.
Файл: MVC\src\MvcFutures\Mvc\ImageExtensions.cs
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(imageRelativeUrl)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
}
UrlHelper url = new UrlHelper(helper.ViewContext.RequestContext);
string imageUrl = url.Content(imageRelativeUrl);
return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
}
Я столкнулся с подобной проблемой и решил, что будет легче просто назвать UrlHelper в представлении и передать вывод моему расширению HtmlHelper. В Вашем случае это было бы похоже:
<%= Html.CreateDialogLink( "text", Url.Content( "~/...path.to.content" ) ) %>
Если Вы хотите получить доступ к дополнительным методам на существующем HtmlHelper, который передается в Ваш класс, необходимо только должны быть импортировать System.Web.Mvc.Html в файле исходного кода, и Вы получите доступ к ним (это - то, где дополнительные классы определяются). Если Вы захотите UrlHelper, то необходимо будет инстанцировать этого как HtmlHelper, который Вы получаете, не имеет дескриптора для ViewPage, из которого он прибывает.
Ну, можно всегда передавать экземпляр страницы к дополнительному методу. Я думаю, что это - намного лучший способ сделать это, чем создание новых экземпляров в Вашем методе.
Вы могли также определить этот метод на классе, который происходит из MasterPage/ViewMasterPage, и затем получите страницу из этого. Таким образом, Вы имеете доступ ко всем свойствам экземпляра и не должны раздавать их.
Если вам нужно создать UrlHelper в служебном классе, вы можете сделать следующее:
string url = "~ / content / images / foo.jpg";
var urlHelper = new UrlHelper(new RequestContext(
new HttpContextWrapper(HttpContext.Current),
new RouteData()), RouteTable.Routes);
string absoluteUrl = urlHelper.Content(url);
Это позволяет вы должны использовать маршрутизацию или расширение "~" вне контекста MVC.