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

React Native中useState首次映射数据丢失的解决方案问询

问题分析与解决方案

问题根源

你的问题出在**useState初始值的计算时机**:

  • initialData 在组件首次挂载时就会被计算,此时如果 accountList 还未完成异步加载(比如从接口获取数据),所有依赖 accountList 的字段都会是 undefined。
  • 当 accountList 后续加载完成后,initialData 不会自动重新生成,Data1 状态也不会同步更新,因此首次打开模态框时数据显示异常。
  • 关闭再打开模态框时,组件会被重新挂载,此时 accountList 已经有了完整数据,initialData 能正确生成,所以状态正常。

修复方案

通过 useEffect 监听 accountList 的变化,在数据就绪时同步更新 Data1 状态,具体步骤如下:

1. 抽离数据生成逻辑

把 initialData 的生成逻辑抽成独立函数,方便复用并做空值处理:

const generateAccountData = () => {
  if (!accountList) return [];
  
  return [
    {
      id: 1,
      name: `${accountList.brideName || ''} ${accountList.brideSurname || ''}`,
      type: 'Gelin',
      selected: false,
      tlText: accountList.brideAccount?.accountTl,
      euroText: accountList.brideAccount?.accountEuro,
      dollarText: accountList.brideAccount?.accountUsd,
      accountHolderType: 'BRIDE'
    },
    {
      id: 2,
      name: `${accountList.groomName || ''} ${accountList.groomSurname || ''}`,
      type: 'Damat',
      selected: false,
      tlText: accountList.groomAccount?.accountTl,
      euroText: accountList.groomAccount?.accountEuro,
      dollarText: accountList.groomAccount?.accountUsd,
      accountHolderType: 'GROOM'
    },
    {
      id: 3,
      name: 'Ortak Hesap',
      type: 'Gelin & Damat ',
      selected: false,
      tlText: accountList.commonAccount?.accountTl,
      euroText: accountList.commonAccount?.accountEuro,
      dollarText: accountList.commonAccount?.accountUsd,
      accountHolderType: 'COMMON'
    },
  ];
};

2. 初始化状态并监听数据变化

修改 useState 的初始化方式,通过 useEffect 在 accountList 更新时同步状态:

const [Data1, setData1] = useState<Data[]>([]);

useEffect(() => {
  // 当accountList更新时,重新生成数据并更新状态
  const newData = generateAccountData();
  setData1(newData);
}, [accountList]); // 依赖accountList,数据变化时触发更新

3. 优化渲染逻辑

添加数据为空时的兜底处理,避免渲染报错,同时修正原代码中的笔误:

<ScrollView showsVerticalScrollIndicator={false}>
  {Data1.length > 0 ? Data1.map((item, index) => {
    console.log('data5 ', accountList?.brideAccount?.accountTl);
    return (
      <View key={item.id}> {/* 添加唯一key属性,符合React渲染规范 */}
        <PressableOpacity
          onPress={() => {
            setSelectedById(item.id);
            console.log('data6 ', accountList?.brideAccount?.accountTl);
          }}>
          <View
            style={{
              paddingVertical: responsiveHeight(13),
              paddingHorizontal: responsiveWidth(24),
              borderBottomWidth: 1,
              borderBottomColor: '#F3F3F3',
              justifyContent: 'center',
            }}>
            <Text
              style={{
                lineHeight: 22,
                fontFamily: Fonts.semiBoldRaleway,
                fontSize: 14,
                letterSpacing: 0.2,
                color: '#000',
              }}>
              {item.name}
            </Text>
            <Text
              style={{
                lineHeight: 16,
                fontFamily: Fonts.regularPetrona,
                fontSize: 10,
                letterSpacing: 0.3,
                color: '#EA80AA',
              }}>
              {item.type}
            </Text>
            <Icon
              style={{
                position: 'absolute',
                right: responsiveWidth(24),
              }}
              name={
                item.selected
                  ? 'chevron-down : feather'
                  : 'chevron-right : feather'
              }
              size={20}
              color="#061937"
            />
          </View>
        </PressableOpacity>
        {item?.selected && (
          <View style={{ paddingHorizontal: responsiveWidth(24) }}>
            <Text>{accountList?.brideAccount?.accountTl}</Text>
            <CustomInput3 value={item?.name} />
            <CustomInput3 leftImage={Images.tlBlack} value={item?.tlText} onChangeText={(value) => handleChangeTl(index, value)} />
            <CustomInput3
              leftImage={Images.dolarBlack}
              value={item?.dollarText}
              onChangeText={(value) => handleChangeDollar(index, value)}
            />
            <CustomInput3
              leftImage={Images.euroBlack}
              value={item.euroText}
              onChangeText={(value) => handleChangeEuro(index, value)}
            />
            <CButton text='Kaydet' onPress={() => {
              onSubmit({ weddingCode: weddingC, accountTl: item.tlText, accountEuro: item.euroText, accountUsd: item.dollarText, accountHolderType: item.accountHolderType })
            }} />
          </View>
        )}
      </View>
    );
  }) : (
    <View style={{ alignItems: 'center', paddingVertical: 40 }}>
      <Text>Yükleniyor...</Text>
    </View>
  )}
</ScrollView>

额外注意点

  • 原代码中渲染时误用了 Data.map,需改为状态变量名 Data1.map。
  • 列表项必须添加唯一 key 属性,避免React渲染警告。
  • 在数据生成函数中添加了空值兜底(|| ''),避免姓名显示为 undefined undefined。

内容的提问来源于stack exchange,提问作者Alperen Kapusuz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:41:06