React中Firebase Realtime Database删除数据失效问题排查
Firebase数据删除失效问题修复方案
核心错误点
你的代码存在4处直接导致后端删除失败、前端逻辑异常的问题:
- 接口路径拼接错误:URL中多余的冒号会导致请求指向不存在的节点,同时你传递的删除标识是map遍历的数组下标,并非Firebase中每条记录的唯一key(也就是你存在
row.key里的节点名),根本匹配不到目标数据 - fetch配置字段拼写错误:请求头配置项应为
headers,你写成了header,会导致请求头未正确携带 - 前端状态更新逻辑冗余且错误:你已经通过
onValue注册了数据库实时监听,后端数据变更后会自动拉取最新数据刷新视图,不需要手动调用filter、splice修改本地state;且你存储的tableData项没有id字段,过滤逻辑永远不生效,splice用下标删除还容易出现删错行的问题 - 交互逻辑顺序错误:你把确认弹窗、成功提示放在请求回调里,不管删除是否成功都会弹出提示,正确顺序应该是用户点击后先弹确认框,确认后再发删除请求
修正后的完整代码
import React, { Component } from 'react' import StartFirebase from "../firebaseConfig/index"; import { ref, onValue} from 'firebase/database'; const db = StartFirebase(); export class TableData extends Component { constructor(props) { super(props); this.state = { tableData: [] } } componentDidMount() { const dbRef = ref(db, 'userRecord') onValue(dbRef, (snapshot) => { let records = [] snapshot.forEach(childSnapshot => { let keyName = childSnapshot.key; let data = childSnapshot.val() records.push({ "key": keyName, "data": data }) }) this.setState({ tableData: records }) }) } DeleteData = async (key) => { // 先弹确认框 const confirmRes = window.confirm('确定要删除这条数据吗?') if (!confirmRes) return try { // 修正URL,去掉多余冒号,用Firebase实际节点key拼接路径 const res = await fetch(`https://clientsdata-dd45a-default-rtdb.firebaseio.com/userRecord/${key}.json`,{ method: 'DELETE', // 修正字段名:header -> headers headers:{ Accept:"application/json", "Content-Type":"application/json" } }) if (res.ok) { window.alert("数据删除成功!") // 不需要手动改state,onValue监听到数据变化会自动刷新 } else { throw new Error('删除失败') } } catch (err) { window.alert("删除失败,请重试") console.error(err) } } render() { return ( <div> <table className="table table-bordered table table-hover"> <thead> <tr> <th>#</th> <th scope="col">ID</th> <th scope="col">Roll</th> <th scope="col">Name</th> <th scope="col">Address</th> <th scope="col">Mobile</th> {/* 补全表头,和列数对应 */} <th scope="col">操作</th> </tr> </thead> <tbody> { this.state.tableData.map((row, index) => { return ( <tr key={row.key}> <th>{row.key}</th> <th scope="row">{index+1}</th> <td>{row.data.userData.RollNum}</td> <td>{row.data.userData.Name}</td> <td>{row.data.userData.Address}</td> <td>{row.data.userData.mobile}</td> <td> <button className='btn btn-danger' // 传递Firebase实际节点key,不是数组下标 onClick={() => this.DeleteData(row.key)} > Delete </button> </td> </tr> ) }) } </tbody> </table> </div> ) } } export default TableData
额外优化点
- 列表渲染的key不要用数组下标,直接用Firebase返回的唯一节点key
row.key,避免增删数据时出现DOM渲染错乱 - 补全了表头缺失的“操作”列,保证表头和表体列数一致,不会出现排版错位
- 加了try/catch错误捕获,删除失败时会给用户提示,不会静默失败
内容的提问来源于stack exchange,提问作者Komal k
相关产品推荐
相关产品推荐

