React Native如何在TextInput值变更时更新字段,实现qty联动扣减qty_total
实现方案
你需要通过修改列表状态实现两个输入框的数值联动,核心逻辑为:
- 计算
qty的调整差值:差值 = 新输入的qty值 - 原有qty值 - 同步更新
qty_total:新qty_total = 原有qty_total - 差值 - 使用不可变更新修改列表数据,触发视图重渲染
完整修改后代码
import React, { useEffect, useRef, useState } from 'react'; import { Dimensions } from 'react-native'; import { Platform } from 'react-native'; import { TouchableOpacity } from 'react-native'; import { View, Text, FlatList, TextInput, StyleSheet, Animated, KeyboardAvoidingView } from 'react-native'; import AxiosInstance from '../../../helper/axiosHelper'; export default function MainList({ prodData, setProdData }) { const [ selectedRow, setSelectedRow ] = useState([]); const [ tempData, setTempData ] = useState([]); const springanim = useRef(new Animated.Value(0)).current; const listanimation = useRef(new Animated.Value(0)).current; useEffect(() => { AxiosInstance.get('/getProdOrders?r_date=2021-07-24&r_force_xtra=0').then((res) => { setTempData(res.data); // 如果列表渲染用tempData就替换下方prodData为tempData即可 setProdData(res.data); }); }, []); // --- 新增联动处理函数 开始 --- const handleQtyChange = (productId, newQtyStr, parentCategoryId) => { const newQty = Number(newQtyStr) || 0; // 不可变更新修改prodData const newProdData = prodData.map(category => { if(category.id !== parentCategoryId) return category; return { ...category, data: category.data.map(item => { if(item.product !== productId) return item; const qtyDiff = newQty - item.qty; return { ...item, qty: newQty, qty_total: item.qty_total - qtyDiff } }) } }) setProdData(newProdData); } // --- 新增联动处理函数 结束 --- // 补充原代码缺失的行选中方法 const handleSelectedRow = (item) => { setSelectedRow(item); } const ProdElem = ({ item, index, parentCategoryId }) => { let bgColor = index % 2 === 0 ? '#363434' : '#5a5656'; return ( <View style={[ { ...styles.container, backgroundColor: bgColor } ]}> <TouchableOpacity onPress={() => handleSelectedRow(item)}> <Text style={styles.productName} numberOfLines={1}> {item.product_name} </Text> </TouchableOpacity> <View style={styles.subContainer}> <View style={styles.qty_readOnly}> <Text style={styles.qty_readOnlyText}>{item.qty_last}</Text> </View> {/* --- 修改qty输入框 绑定value和变更事件 --- */} <TextInput style={styles.qty} keyboardType='numeric' name='qty' value={String(item.qty)} onChangeText={(val) => handleQtyChange(item.product, val, parentCategoryId)}> </TextInput> {/* --- 修改qty_total输入框 绑定value,不需要编辑可加editable={false} --- */} <TextInput style={styles.qty} keyboardType='numeric' value={String(item.qty_total)} editable={false}> </TextInput> <View style={styles.qty_readOnly}> <Text style={styles.qty_readOnlyText}>{item.qty_post_order}</Text> </View> </View> </View> ); }; const renderItem = ({ item }) => { let sumPre = 0, sumExtra = 0, sumTotal = 0, sumAvailabe = 0; item.data.forEach((e) => { sumPre += e.qty_last; sumExtra += e.qty; sumTotal += e.qty_total; sumAvailabe += e.qty_post_order; }); return ( <View> <FlatList listKey={(item, index) => 'D' + index.toString()} data={item.data} renderItem={(props) => <ProdElem {...props} parentCategoryId={item.id} />} keyExtractor={(e) => e.product} /> <View style={styles.categoryContainer}> <Text style={styles.categoryName}>{item.title}</Text> <View style={styles.totals}> <Text style={styles.total_qty_readonly}>{sumPre}</Text> <Text style={styles.total_qty}>{sumExtra}</Text> <Text style={styles.total_qty}>{sumTotal}</Text> <Text style={styles.total_qty_readonly}>{sumAvailabe}</Text> </View> </View> </View> ); }; useEffect( () => { Animate(false); }, [ springanim ] ); return ( <View> <Animated.View style={{ paddingBottom: listanimation }}> <FlatList data={prodData} listKey={'cat'} keyExtractor={(item) => item.id} renderItem={renderItem} /> </Animated.View> <Animated.View style={{ position : 'absolute', fontSize : 25, backgroundColor : 'white', width : Dimensions.get('screen').width, padding : 20, bottom : springanim }}> <Text> Name: {selectedRow.product_name} <Text style={{ color: '#a0a0a0' }}>/ {selectedRow.revision}</Text> </Text> <Text style={{ fontWeight: 'bold' }}>Kind: {selectedRow.kind}</Text> <Text style={{ fontWeight: 'bold' }}>PCS: {selectedRow.qty_total}</Text> <Text style={{ fontWeight: 'bold' }}>Available: {selectedRow.qty}</Text> </Animated.View> </View> ); }
可选优化点
- 增加输入校验,避免qty_total出现负数的异常场景
- 如果需要允许用户直接修改qty_total,可按同样逻辑补充qty_total的变更事件,反向计算qty的值
内容的提问来源于stack exchange,提问作者samer g
相关产品推荐
相关产品推荐

