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
相关产品推荐
相关产品推荐

