React Native实现数组多选框及条件金额累加功能
解决React Native多选框选中金额累加问题
需求
为每个发票项添加独立多选框,选中时累加对应剩余金额:选中第一项总金额显示10.00,两项都选显示30.00。
API响应数据
const invoiceResponse = [ { remainingAmount: { unit: "GHS", value: "10.00", }, id: "FINV-101010632629-22", }, { remainingAmount: { unit: "GHS", value: "20.00", }, id: "FINV-101010632345-33", }, ];
修改后的完整代码
import React, { useState, useMemo } from 'react'; import { View } from 'react-native'; import CustomText from './CustomText'; import Checkbox from './Checkbox'; // 引入项目已有的styles、themeObj、formatDate等依赖 const InvoiceScreen = () => { // 用数组存储选中的发票ID,实现独立多选控制 const [selectedIds, setSelectedIds] = useState([]); // 计算选中项总金额,useMemo优化性能,仅在选中状态变化时重新计算 const totalAmount = useMemo(() => { return selectedIds.reduce((total, id) => { const invoice = invoiceResponse.find(item => item.id === id); return total + parseFloat(invoice?.remainingAmount.value || 0); }, 0).toFixed(2); }, [selectedIds]); // 切换单个发票的选中状态 const toggleInvoiceSelection = (invoiceId) => { setSelectedIds(prev => { return prev.includes(invoiceId) ? prev.filter(id => id !== invoiceId) : [...prev, invoiceId]; }); }; return ( <> {formValues.activeTab === "By Invoice" && invoiceResponse.map((data) => { const isChecked = selectedIds.includes(data.id); return ( <View key={data.id}> {/* 用发票唯一ID作为key,避免索引导致的渲染异常 */} <View style={{ backgroundColor: "white", borderRadius: 10, height: hp("10%"), marginTop: hp("1%"), }} > <View style={{ backgroundColor: "white", padding: hp("2%"), borderRadius: 10, flexDirection: "row", justifyContent: "space-between", }} > <View> <CustomText text={data.id} textStyle={[ styles.textH3, { color: themeObj.buttonTextColor }, ]} /> <View style={{ flexDirection: "row" }}> <CustomText text={"Remaining Amount: "} textStyle={[styles.btnTxtMed, { color: "#777777" }]} /> <CustomText text={parseFloat(data.remainingAmount.value).toFixed(2)} textStyle={[ styles.btnTxtMed, { color: themeObj.buttonTextColor }, ]} /> </View> <View style={{ flexDirection: "row" }}> <CustomText text={"Due date: "} textStyle={[styles.btnTxtMed, { color: "#777777" }]} /> <CustomText text={formatDate(data.paymentDueDate)} textStyle={[ styles.btnTxtMed, { color: themeObj.buttonTextColor }, ]} /> </View> </View> <View> <Checkbox status={isChecked ? "checked" : "unchecked"} onPress={() => toggleInvoiceSelection(data.id)} color={"#FC0"} /> </View> </View> <CustomText text={`Total amount: ${totalAmount} ${invoiceResponse[0]?.remainingAmount.unit}`} textStyle={[ styles.btnTxtMed, { color: themeObj.buttonTextColor }, ]} /> </View> </View> ); })} </> ); }; export default InvoiceScreen;
关键修改说明
- 状态管理优化:将单个布尔值
checked改为存储选中发票ID的数组selectedIds,解决原代码中所有复选框同步状态的问题,实现独立多选。 - 多选框状态绑定:每个复选框的状态由当前发票ID是否在
selectedIds数组中决定,确保选中状态独立可控。 - 总金额计算:通过
reduce累加选中项的剩余金额,用toFixed(2)保证格式为两位小数;useMemo缓存计算结果,避免不必要的重复计算。 - 列表Key优化:使用发票唯一ID作为列表项的
key,替代索引,提升列表渲染稳定性。
内容的提问来源于stack exchange,提问作者abhigyan kr
相关产品推荐
相关产品推荐

