React Native中如何获取多个输入框值并求和?
实现多日里程数求和及剩余里程计算
问题分析与解决步骤
1. 修复里程数状态更新的问题
你的handleChange函数目前在更新某一天的里程时,会直接替换整个miles对象,导致其他天数的里程数据丢失。需要用展开运算符保留原有状态,只更新当前修改的天数:
const handleChange = (day, value) => { // 将输入值转为数字,空输入默认设为0 const numValue = Number(value) || 0; setMiles(prev => ({ ...prev, // 保留之前所有天数的里程数据 [day]: numValue })); };
2. 计算所有天数的里程总和
使用Object.values(miles)提取所有天数的里程值,再用array.reduce()求和,同时处理类型转换和初始值:
// 计算已完成的总里程 const totalMiles = Object.values(miles).reduce((sum, current) => sum + current, 0); // 计算剩余里程,处理目标里程为空的情况 const milesToGo = goal ? Number(goal) - totalMiles : 0;
3. 优化初始状态
为避免undefined导致的计算错误,给goal设置初始值0:
const [goal, setGoal] = useState(0);
修改后的完整代码
import React, { useState } from "react"; import { View, Text, StyleSheet, TextInput, ScrollView } from 'react-native'; const Goal = () => { const [goal, setGoal] = useState(0); const [miles, setMiles] = useState({ monday: 0, tuesday: 0, // wednesday: 0, // thursday: 0, // friday: 0, // saturday: 0, // sunday: 0, }); const handleChange = (day, value) => { const numValue = Number(value) || 0; setMiles(prev => ({ ...prev, [day]: numValue })); }; // 计算总里程和剩余里程 const totalMiles = Object.values(miles).reduce((sum, current) => sum + current, 0); const milesToGo = goal ? Number(goal) - totalMiles : 0; return ( <ScrollView> {/* 设置目标里程 */} <View style={styles.goalContainer}> <Text style={styles.goalText}> 目标里程: {goal} 剩余里程: {milesToGo} </Text> <View style={styles.inputContainer}> <TextInput style={styles.goalInput} placeholder="输入目标里程" keyboardType="numeric" value={String(goal)} onChangeText={(value) => setGoal(Number(value) || 0)} /> </View> </View> <View style={styles.weekDayContainer}> <View> <Text style={styles.weekDayText}>周一</Text> <TextInput style={styles.weekDayInput} placeholder="输入里程" keyboardType="numeric" value={String(miles.monday)} onChangeText={(value) => handleChange('monday', value)} /> </View> <View> <Text style={styles.weekDayText}>周二</Text> <TextInput style={styles.weekDayInput} placeholder="输入里程" keyboardType="numeric" value={String(miles.tuesday)} onChangeText={(value) => handleChange('tuesday', value)} /> </View> </View> </ScrollView> ) } const styles = StyleSheet.create({ goalContainer: {}, goalText: { fontSize: 30, marginBottom: 30, }, goalInput: { height: 50, width: 200, textAlign: 'center', borderWidth: 1, borderRadius: 60, marginRight: 16, }, weekDayInput: { borderBottomWidth: 1, width: 100, height: 40, marginBottom: 10, textAlign: 'center', }, weekDayContainer: { marginTop: 80, marginLeft: 50, }, weekDayText: { fontSize: 20, marginBottom: 10, }, }); export default Goal;
关键说明
- 所有输入值统一转为数字类型,避免字符串拼接导致的计算错误
- 使用
prev参数获取上一次的state,确保状态更新的稳定性 - 处理了空输入的边界情况,默认设为0,避免出现NaN
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

