我正在开发一个 React 家庭自动化项目,在第一个模块“灯”中,我将所有家庭灯的状态存储在 Firebase 数据库中。我已经成功在我的应用程序中创建了一个切换功能,并且它可以快速写入数据库。那里没有问题。 我的问题:我的所有切换按钮都是简单的文本,单击时会通过条件 SCSS
类更改颜色,但这不是问题所在。当然,我独立于数据库开发了切换方法,因此每当刷新页面并重新渲染组件时,所有按钮都会设置为其初始状态(全部关闭)。我需要做的是找出一种方法将按钮与其在 Firebase 中的相应值同步。当然,我可以为每个按钮索引设置一个状态,但我认为包装器切换状态会更有效。无论如何,我意识到这里简单且最好的解决方案是更新 componentDidMound()
方法中的切换 state
,以便其余的切换可以独立于数据库并继续显示正确的值,但是当我尝试将数据传递到我的状态时,它会抛出一个错误,指出它无法读取未定义的状态。 constructor()
也是如此,如下所示。我已经测试了 Firebase
返回的数据,并且它在应该有的时候将 true
/false
打印到控制台,那么我该如何传递将数据从 Firebase
发送到状态?我在初始化按钮时采取了错误的方法吗?
这是我的包含上述问题的组件:
import React, {Component} from "react"
import * as firebase from "firebase"
import colors from "colors"
var config = {
apiKey: "SSSSSSUUUUPPPPEEERRRRLLOONNGGKKKKEEEEYYYYYY!!!",
authDomain: "something-someNumbers.firebaseapp.com",
databaseURL: "https://something-someNumbers.firebaseio.com",
projectId: "something-someNumbers",
storageBucket: "something.appspot.com",
messagingSenderId: "1111111111"
}
firebase.initializeApp(config)
class Cards extends Component {
render() {
return (
<div>
<div id="toolbar-spacer"/>
<div id="wrapper-div">
<Lights/>
</div>
</div>
)
}
}
class Card extends Component {
render() {
return(
<div className="card-container">
{this.props.children}
</div>
)
}
}
class Lights extends Component {
constructor(props) {
super(props)
}
render() {
return(
<Card>
<div className="link-wrapper">
{[
{room: 'Office'},
{room: 'Office Bathroom'},
{room: 'Neekon Bedroom'},
{room: 'Ryan Room'},
{room: 'Homework Room'},
{room: 'Living Room'},
{room: 'Gallery'},
{room: 'Guest Bathroom'},
{room: 'Dining Room'},
{room: 'Kitchen'},
{room: 'Master Bedroom'},
{room: 'Family Room'}
].map((item, i) => {
return (
<Room lumer={"s" + item.room.replace(" ", "")} key={i}>
{item.room}
</Room>
)
})}
</div>
<div id="card-title-footer" />
<div className="link-wrapper">
<Room lumer={"all"}>
All Lights
</Room>
</div>
</Card>
)
}
}
class Room extends Component {
constructor(props) {
super(props);
var room = this.props.lumer
var staate;
firebase.database()
.ref()
.child('/rooms/' + room)
.once('value')
.then(function(snapshot) {
staate = snapshot.val()
console.log(staate)
})
const {isToggleOn} = staate
this.state = { isToggleOn }
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
console.log(this.props.lumer + ': mounted!')
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
var database = firebase.database()
firebase.database().ref().child('/rooms/' + this.props.lumer).set(!this.state.isToggleOn);
console.log(this.props.lumer + ": " + !this.state.isToggleOn)
}
render() {
return (
<a onClick={this.handleClick} className={this.state.isToggleOn ? "toggle-text-on" : "toggle-text-off"}>
{this.state.isToggleOn ? this.props.children + ': ON' : this.props.children + ': OFF'}
</a>
)
}
}
export default Cards
PS:我的github repo如果有的话,可能会为一些不清楚的引用文献提供上下文
我们将感激并乐意接受任何和所有的帮助。谢谢!
最佳答案
我明白了! (来 self 的一位开发者 friend )
问题是它没有生成正确类型的对象来放置在我的状态中。事实上,我什至根本不需要生成一个对象!我所需要做的就是在 firebase
回调中使用 this.setState({})
(使用 () => {function}
),而不是传统的),然后简单地直接在状态中传递我的变量,如下所示:
componentDidMount() {
var room = this.props.lumer
var staate;
firebase.database()
.ref()
.child('/rooms/' + room)
.once('value')
.then( (snapshot) => {
state = snapshot.val()
this.setState({
isToggleOn: state
})
})
}
关于javascript - 在react状态下初始化pass firebase值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44836700/