You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何正确对Firebase获取的两个数值字段求和

问题现象

React开发过程中,对Firebase实时数据库读取到的contactObjects[id].gcc、contactObjects[id].lcc两个字段执行加法计算时,始终得到字符串拼接结果而非数值求和结果:当两个字段存储值分别为10、30时,现有代码输出10 + 30,而非预期的40。

附原问题相关实现代码:

import React, { useState, useEffect } from "react";
import ContactForm from "./ContactForm";
import firebaseDb from "../firebase";

const Contacts = () => {
  var [contactObjects, setContactObjects] = useState({});
  var [currentId, setCurrentId] = useState("");

  useEffect(() => {
    firebaseDb.child("contacts").on("value", (snapshot) => {
      if (snapshot.val() != null)
        setContactObjects({
          ...snapshot.val(),
        });
      else setContactObjects({});
    });
  }, []); 

  const addOrEdit = (obj) => {
    if (currentId == "")
      firebaseDb.child("contacts").push(obj, (err) => {
        if (err) console.log(err);
        else setCurrentId("");
      });
    else
      firebaseDb.child(`contacts/${currentId}`).set(obj, (err) => {
        if (err) console.log(err);
        else setCurrentId("");
      });
  };

  const onDelete = (key) => {
    if (window.confirm("Are you sure to delete this record?")) {
      debugger;
      firebaseDb.child(`contacts/${key}`).remove((err) => {
        if (err) console.log(err);
        else setCurrentId("");
      });
    }
  };

  return (
    <>
      <div className="jumbotron jumbotron-fluid">
        <div className="container">
          <h1 className="display-4 text-center">Contact Register</h1>
        </div>
      </div>
      <div className="row">
        <div className="col-md-5">
          <ContactForm {...{ addOrEdit, currentId, contactObjects }} />
        </div>
        <div className="col-md-7">
          <table className="table table-borderless table-stripped">
            <thead className="thead-light">
              <tr>
                <th>Full Name</th>
                <th>Mobile</th>
                <th>Email</th>
                <th>Address</th>
                <th>Street</th>
                <th>Address</th>
                <th>Gcc</th>
                <th>Lcc</th>
              </tr>
            </thead>
            <tbody>
              {Object.keys(contactObjects).map((id) => {
                return (
                  <tr key={id}>
                    <td>{contactObjects[id].fullName}</td>
                    <td>{contactObjects[id].mobile}</td>
                    <td>{contactObjects[id].email}</td>
                    <td>{contactObjects[id].address}</td>
                    <td>{contactObjects[id].street}</td>
                    <td>{contactObjects[id].gcc}</td>
                    <td>{contactObjects[id].lcc}</td>
                    <td>
                      {contactObjects[id].gcc} +
                      {contactObjects[id].lcc}
                    </td>
                    <td>
                      <a
                        className="btn text-primary"
                        onClick={() => {
                          setCurrentId(id);
                        }}
                      >
                        <i className="fas fa-pencil-alt"></i>
                      </a>
                      <a
                        className="btn text-danger"
                        onClick={() => {
                          onDelete(id);
                        }}
                      >
                        <i className="far fa-trash-alt"></i>
                      </a>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
};

export default Contacts;
问题原因

两个问题共同导致结果不符合预期:

  1. JSX写法错误:当前代码把+符号放在了JSX表达式的大括号外面,属于普通文本节点,最终渲染效果是依次输出gcc的值、文本+、lcc的值,根本没有执行加法运算。
  2. 类型不匹配:Firebase读取到的字段值默认是字符串类型,就算把+放到大括号内执行运算,JS也会执行字符串拼接而非数值求和。
修复方案

1. 修正渲染层计算逻辑

把求和逻辑放到同一个JSX表达式大括号内,计算前先把两个字段值转为数值类型,替换原有错误的求和列代码:

<td>
  {/* 用Number转数值后相加,加||0兜底避免空值转成NaN */}
  {(Number(contactObjects[id].gcc) || 0) + (Number(contactObjects[id].lcc) || 0)}
</td>

常用的数值转换方式可按需选择:

  • Number(val):通用转换,支持整数、浮点数
  • parseInt(val, 10):仅转整数,需要指定进制参数10避免兼容问题
  • parseFloat(val):转浮点数
  • +val:隐式转换写法,代码更简洁

2. 根源优化:写入数据时统一类型

在数据写入Firebase的逻辑中提前把gcc、lcc转为数值类型存储,后续读取时无需每次做类型转换:

const addOrEdit = (obj) => {
  // 写入前预处理数值字段
  const saveData = {
    ...obj,
    gcc: Number(obj.gcc) || 0,
    lcc: Number(obj.lcc) || 0
  }
  if (currentId == "")
    firebaseDb.child("contacts").push(saveData, (err) => {
      if (err) console.log(err);
      else setCurrentId("");
    });
  else
    firebaseDb.child(`contacts/${currentId}`).set(saveData, (err) => {
      if (err) console.log(err);
      else setCurrentId("");
    });
};

内容的提问来源于stack exchange,提问作者Iliya Shatami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:24:21