React Native:FlatList文本输入存入数组时旧值被覆盖问题求助
React Native FlatList中TextInput输入值被覆盖的问题解决
问题描述
在React Native中使用FlatList展示API返回的数据,每个列表项包含TextInput组件,需将每个输入框的内容存入数组。当前问题:填写第一个输入框时数组正常填充,但填写其他输入框时,之前的数值会被新值替换。
原代码
状态与输入处理逻辑
const [tareas, setTareas] = useState([]); var T_array = []; const inputHandler = (text, id) => { T_array.push({cantidad:text, id: id}) setTareas(T_array); console.log(T_array); };
FlatList渲染代码
<SafeAreaView style={{ flex: 0.7 }}> <FlatList showsVerticalScrollIndicator={false} //scrollEnabled={false} data={tareas_data} renderItem={({ item, index }) => ( <View style={styles.listContainer}> <View style={styles.genContainer}> <Text style={styles}>Descripción: {item.accion} de</Text> <View> <Text style={styles}> {item.quantity} {item.item} </Text> <Text style={styles.group}>Se Realiza {item.accion} de </Text> <TextInput containerStyle="" style={styles.inputNumber} keyboardType="numeric" defaultValue="0" maxLength={2} key={index} onChangeText={(text) => inputHandler(text, item.id)} ></TextInput> <Text style={styles}>{item.item}</Text> </View> </View> </View> )} keyExtractor={(item) => item.id} /> </SafeAreaView>
问题原因
- 全局变量重置:
T_array是组件外部的全局变量,每次组件重新渲染时都会被重置为空数组,导致旧数据丢失。 - 未处理重复id更新:每次调用
inputHandler直接push新对象,没有检查数组中是否已有对应id的项,导致重复添加或覆盖逻辑错误。 - 状态更新不规范:直接修改原数组后调用
setTareas,违反React状态不可变原则,可能导致状态更新不及时或异常。
解决方案
修改后的状态与输入处理逻辑
const [tareas, setTareas] = useState([]); const inputHandler = (text, id) => { setTareas(prevTareas => { // 查找当前id对应的项是否存在 const targetIndex = prevTareas.findIndex(item => item.id === id); if (targetIndex !== -1) { // 存在则更新该项的输入值 const updatedList = [...prevTareas]; updatedList[targetIndex] = { ...updatedList[targetIndex], cantidad: text }; return updatedList; } else { // 不存在则添加新项 return [...prevTareas, { cantidad: text, id: id }]; } }); };
修改后的FlatList渲染代码
<SafeAreaView style={{ flex: 0.7 }}> <FlatList showsVerticalScrollIndicator={false} data={tareas_data} renderItem={({ item }) => ( <View style={styles.listContainer}> <View style={styles.genContainer}> <Text style={styles}>Descripción: {item.accion} de</Text> <View> <Text style={styles}> {item.quantity} {item.item} </Text> <Text style={styles.group}>Se Realiza {item.accion} de </Text> <TextInput containerStyle="" style={styles.inputNumber} keyboardType="numeric" maxLength={2} key={item.id} // 改用item.id作为key,避免列表变动时的渲染异常 onChangeText={(text) => inputHandler(text, item.id)} // 绑定value实现受控组件,确保输入框内容与状态同步 value={tareas.find(t => t.id === item.id)?.cantidad || "0"} /> <Text style={styles}>{item.item}</Text> </View> </View> </View> )} keyExtractor={(item) => item.id} /> </SafeAreaView>
关键修改点说明
- 函数式状态更新:使用
setTareas(prevTareas => ...)确保每次更新基于最新的状态值,避免状态异步更新导致的错误。 - id匹配更新:通过
findIndex检查是否已有对应id的项,实现"更新已有项、添加新项"的逻辑,避免数据覆盖。 - 受控组件绑定:给TextInput添加
value属性,使输入框内容与tareas状态双向同步,保证显示内容准确。 - 稳定key设置:将TextInput的key从
index改为item.id,避免列表项排序或增删时出现组件复用异常。
内容的提问来源于stack exchange,提问作者userNotFound21
相关产品推荐
相关产品推荐

