React集成Firebase DB:添加多子节点报错求助
问题分析与修复方案
嘿,我一眼就揪出导致你报错的原因啦!咱们一步步来解决:
1. 直接触发报错的核心问题
你看submitBug方法里的这段代码:
const nextBug = { id: this.state.bugs.length, station: this.state.title, // 这里错了! bug: this.state.bug, desc: this.state.desc }
你的state里定义的是station字段,但这里写成了this.state.title——这个属性根本不存在,所以station自然就是undefined,直接触发了Firebase的报错!
修复方法:把this.state.title改成this.state.station。
2. 其他潜在问题(避免后续踩坑)
除了上面的直接错误,还有几个地方需要调整,不然后续会遇到新问题:
(1)Firebase返回的数据是对象,不能直接用map遍历
在componentDidMount里,snapshot.val()返回的是一个键值对对象,而不是数组,直接用this.state.bugs.map会报错。需要把对象转成数组:
componentDidMount() { firebase.database().ref('bugs/').on ('value', (snapshot) => { const currentBugs = snapshot.val() if (currentBugs != null) { // 把对象转成数组 const bugsArray = Object.values(currentBugs) this.setState({ bugs: bugsArray }) } }) }
(2)用bugs.length作为id有隐患
如果删除了某个中间的bug,新添加的bug id会和已存在的重复。建议用Firebase的push()方法自动生成唯一id,这样更可靠:
submitBug(event) { event.preventDefault() // 防止页面刷新 const nextBug = { station: this.state.station, bug: this.state.bug, desc: this.state.desc } // 用push生成唯一id,不需要自己管理id firebase.database().ref('bugs/').push(nextBug) }
这样修改后,你还需要调整render里的key,因为现在id是Firebase生成的随机字符串,比如用遍历索引作为临时key:
<li key={i}>{bug.station}</li>
(3)添加表单提交的默认行为阻止
在submitBug开头加上event.preventDefault(),避免点击按钮后页面自动刷新丢失状态。另外可以在提交后清空表单,提升用户体验。
修改后的完整代码
import React, { Component } from 'react'; import { Button } from "react-bootstrap"; import withAuthorization from './withAuthorization'; import * as firebase from 'firebase'; class HomePage extends Component { constructor(props,context) { super(props,context); this.stationBug = this.stationBug.bind(this) this.issueBug = this.issueBug.bind(this) this.descBug = this.descBug.bind(this) this.submitBug = this.submitBug.bind(this) this.state = { station: '', bug: '', desc: '', bugs: [] } } componentDidMount() { firebase.database().ref('bugs/').on ('value', (snapshot) => { const currentBugs = snapshot.val() if (currentBugs != null) { // 将Firebase返回的对象转为数组 const bugsArray = Object.values(currentBugs) this.setState({ bugs: bugsArray }) } }) } stationBug(event) { this.setState({ station: event.target.value }); } issueBug(event) { this.setState({ bug: event.target.value }); } descBug(event) { this.setState({ desc: event.target.value }); } submitBug(event) { event.preventDefault() // 阻止页面默认刷新行为 const nextBug = { station: this.state.station, // 修正了属性名错误 bug: this.state.bug, desc: this.state.desc } // 使用push生成唯一id,无需手动管理id firebase.database().ref('bugs/').push(nextBug) // 提交后清空表单 this.setState({ station: '', bug: '', desc: '' }) } render() { return ( <div className="App"> { this.state.bugs.map((bug, i) => { return ( <li key={i}>{bug.station} - {bug.bug}</li> ) }) } <input onChange={this.stationBug} type="text" placeholder="Station #" value={this.state.station} /> <br /> <textarea onChange={this.issueBug} type="text" placeholder="Bug/Issue" value={this.state.bug} /> <br /> <textarea onChange={this.descBug} type="text" placeholder="Bug Description" value={this.state.desc} /> <br /> <Button onClick={this.submitBug} type="button"> Enter Bug </Button> </div> ); } } export default withAuthorization()(HomePage);
内容的提问来源于stack exchange,提问作者namesjj
相关产品推荐
相关产品推荐

