Firebase实时数据库数据加载到React Hook组件后如何实现表单同步
问题修复方案
你代码中的核心问题如下:
- 初始状态
userData错误定义为字符串类型,但实际需要用对象存储配置,初始值应设为{} - 读取实时数据库数据的逻辑错误,你将对象结构的快照遍历存入数组后赋值给
userData,导致后续无法通过userData.pos1_a这类属性读取值 - 未在组件卸载时移除实时数据库的监听,会造成内存泄漏
- 提交更新时的数据库路径写错,读取的是
/pos/pos1,写入时错误写成了/pos/post1 - 输入框的
onChange事件未正确获取输入值,你拿到的是事件对象,需要取target.value属性 - 第三个输入框(userData_C)复制粘贴错误,绑定和修改的都是
pos1_b属性,没有对应pos1_c - ReactStrap的Button组件在web端没有
onPress属性,应该用onClick触发提交事件
修正后的完整代码如下:
import React, { useState, useEffect } from "react"; import firebase from "firebase"; import { Row, Col, Button, CardTitle, } from "reactstrap"; const Configs = () => { // 初始值改为空对象 const [userData, setUserData] = useState({}); // 把数据库引用提出来,方便后续清理监听 const posRef = firebase.database().ref("/pos/pos1"); const getUser = () => { posRef.on("value", (snapshot) => { // 直接获取快照值,不需要遍历转数组 const data = snapshot.val() || {}; console.log(JSON.stringify(data, null, 2)); setUserData(data); }) }; useEffect(() => { getUser(); // 组件卸载时移除监听 return () => posRef.off("value"); }, []); const handleUpdate = () => { // 路径和读取保持一致,不要多写t posRef.update({ pos1_a: Number(userData.pos1_a) || 0, pos1_b: Number(userData.pos1_b) || 0, pos1_c: Number(userData.pos1_c) || 0, }) .then(()=> { console.log('Pos Updated') }) .catch(err => console.log('更新失败:', err)) }; return ( <React.Fragment> <div className="page-content"> <Row> <Col> <CardTitle className="h4">Main Configurations</CardTitle> <p className="card-title-desc"> Settings will be written on<code> database</code> applied to the webhook loads <code><input></code> <code>type</code> . </p> <Row className="mb-3"> <label htmlFor="example-text-input" className="col-md-2 col-form-label" > userData_A </label> <div className="col-md-10"> <div> <input className="form-control" type="number" min="0" value={userData?.pos1_a ?? ""} onChange={(e) => setUserData({ ...userData, pos1_a: e.target.value, }) } /> </div> </div> </Row> <Row className="mb-3"> <label htmlFor="example-search-input" className="col-md-2 col-form-label" > userData_B </label> <div className="col-md-10"> <div> <input className="form-control" type="number" min="0" value={userData?.pos1_b ?? ""} onChange={(e) => setUserData({ ...userData, pos1_b: e.target.value, }) } /> </div> </div> </Row> <Row className="mb-3"> <label htmlFor="example-search-input" className="col-md-2 col-form-label" > userData_C </label> <div className="col-md-10"> <div> <input className="form-control" type="number" min="0" value={userData?.pos1_c ?? ""} onChange={(e) => setUserData({ ...userData, pos1_c: e.target.value, }) } /> </div> </div> </Row> <Button buttonTitle="Update" color="primary" type="button" onClick={handleUpdate} > Submit change </Button> </Col> </Row> </div> </React.Fragment> ); }; export default Configs;
修正后自动实现双向同步:实时数据库的/pos/pos1节点数据发生变化时,表单会自动更新为最新值;修改表单内容点击提交后,数据会写入到数据库对应节点。
内容的提问来源于stack exchange,提问作者Tabliz
相关产品推荐
相关产品推荐

