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

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>

问题原因

  1. 全局变量重置:T_array是组件外部的全局变量,每次组件重新渲染时都会被重置为空数组,导致旧数据丢失。
  2. 未处理重复id更新:每次调用inputHandler直接push新对象,没有检查数组中是否已有对应id的项,导致重复添加或覆盖逻辑错误。
  3. 状态更新不规范:直接修改原数组后调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:24:29