You need to enable JavaScript to run this app. React Native点击可触摸项时如何更新对象数组状态与屏幕样式
优惠活动
大模型
产品
解决方案
定价
更多

React Native点击可触摸项时如何更新对象数组状态与屏幕样式

问题根因

  • 你定义的loanAmountArray、durationArray是组件内的普通变量,没有存入React状态,修改这类变量不会触发组件重渲染,界面自然不会更新
  • 数组修改采用了直接修改原对象属性的可变操作,就算存入state,这种操作也无法让React检测到状态变化
  • updateDataArray方法逻辑错误:遍历时判断的是整个数组的id属性而非数组每一项的id,本身就不能正确修改选中状态
  • useState的更新是异步操作,刚调用setSelectedDurationId就读取selectedDurationId拿到的是更新前的旧值,逻辑会出错

修正方案

直接把两个数据源存入state,采用不可变方式更新即可,不需要单独维护选中id的状态,修正后的完整代码如下:

import React, {useState} from 'react';
import {ScrollView, FlatList, View, Text, TouchableOpacity} from 'react-native';

import styles from './styles';

export default function Loans() {
  // 把数据源存入state,依靠state更新触发重渲染
  const [loanAmountArray, setLoanAmountArray] = useState([
    {
      id: 1,
      amount: '5,000',
      selected: 'yes',
    },
    {
      id: 2,
      amount: '10,000',
      selected: 'no',
    },
    {
      id: 3,
      amount: '20,000',
      selected: 'no',
    },
  ]);

  const [durationArray, setDurationArray] = useState([
    {
      id: 1,
      days: '30 days',
      rate: '3.3% Interest',
      selected: 'yes',
    },
    {
      id: 2,
      days: '60 days',
      rate: '5% Interest',
      selected: 'no',
    },
    {
      id: 3,
      days: '90 days',
      rate: '7% Interest',
      selected: 'no',
    },
  ]);

  // 金额选中逻辑,不可变更新数组
  const changeSelectedAmount = (id) => {
    setLoanAmountArray(prev => prev.map(item => ({
      ...item,
      selected: item.id === id ? 'yes' : 'no'
    })));
  };

  // 期限选中逻辑,不可变更新数组
  const changeSelectedDuration = (id) => {
    setDurationArray(prev => prev.map(item => ({
      ...item,
      selected: item.id === id ? 'yes' : 'no'
    })));
  };

  return (
    <View style={{flex: 1}}>
      <ScrollView>
        <View style={styles.contain}>
          <Text>选择贷款金额</Text>
          <FlatList
            numColumns={6}
            data={loanAmountArray}
            keyExtractor={(item) => item.id.toString()}
            renderItem={({item}) => {
              return (
                <View>
                  <TouchableOpacity
                    onPress={() => changeSelectedAmount(item.id)}
                  >
                    <Text
                      style={
                        item.selected === 'yes'
                          ? styles.textBoxSelected
                          : styles.textBox
                      }
                    >
                      {item.amount}
                    </Text>
                  </TouchableOpacity>
                </View>
              );
            }}
          />

          <Text>选择还款期限</Text>
          <FlatList
            numColumns={3}
            data={durationArray}
            keyExtractor={(item) => item.id.toString()}
            renderItem={({item}) => {
              return (
                <View>
                  <TouchableOpacity
                    style={
                      item.selected === 'yes'
                        ? styles.durationViewPressed
                        : styles.durationView
                    }
                    onPress={() => changeSelectedDuration(item.id)}
                  >
                    <View>
                      <Text style={styles.interest}>{item.rate}</Text>
                    </View>
                    <View>
                      <Text style={styles.days}>{item.days}</Text>
                    </View>
                  </TouchableOpacity>
                </View>
              );
            }}
          />
        </View>
      </ScrollView>
    </View>
  );
}

样式代码不需要做任何修改,原有样式可以直接复用。

内容的提问来源于stack exchange,提问作者MIike Eps

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 21:06:03