React Native动态列表中onPress悬停效果异常问题求助
修复方案:列表中点击单张图片仅显示对应文本
你遇到的问题根源是全局布尔状态showText被所有列表项共享,点击任何一项都会切换这个全局状态,导致所有图片的文本同时显示/隐藏。解决思路是用「记录当前激活项的唯一标识」替代全局布尔值,让每个列表项只判断自己是否是激活项。
修改步骤:
- 替换状态定义:把全局布尔状态改成记录激活项ID(或索引)的状态
- 更新点击逻辑:点击时切换当前激活项(如果点击的是已激活项则取消激活)
- 调整文本显示条件:仅当当前项是激活项时显示文本
修改后的完整代码
import Button from "../custom-components/Button"; import React, { useState, useEffect } from "react"; import { Image, ImageBackground, StyleSheet, TouchableOpacity, Text, View, FlatList, } from "react-native"; import { ScrollView } from "react-native-gesture-handler"; import axios from "axios"; import { API_URL } from "@env"; import { useSelector } from "react-redux"; export default function App() { const languageState = useSelector((state) => state.languageReducer); const [xx43d, setxx43d] = React.useState(languageState.language); // 用activeItemId记录当前激活的项的唯一标识(优先用item自带的id,没有则用索引) const [activeItemId, setActiveItemId] = useState(null); const [apiData, setApiData] = useState([]); React.useEffect(() => { axios .get(`${API_URL}/xyxsnn?xx43d=${xx43d}`) .then((response) => { if (response.status === 200) { setApiData(response.data.result); } }) .catch((errors) => { console.log(errors); }); }, []); return ( <> <ScrollView> <FlatList data={apiData} numColumns={2} // 优先用item的唯一id作为key,没有则用名称(保证唯一性即可) keyExtractor={(item) => item.id || item.name} renderItem={({ item }) => ( <TouchableOpacity activeOpacity={0.5} // 点击时切换激活状态:如果当前项已激活则取消,否则设置为当前项的id onPress={() => setActiveItemId(activeItemId === item.id ? null : item.id)} > <ImageBackground source={{ uri: "https://reactjs.org/logo-og.png" }} resizeMode="cover" style={styles.image} > {/* 仅当当前项是激活项时显示文本 */} {activeItemId === item.id && <Text style={styles.text}>{item.name}</Text>} </ImageBackground> </TouchableOpacity> )} /> </ScrollView> </> ); } const styles = StyleSheet.create({ container: { flex: 1, }, image: { justifyContent: "center", height: 250, width: 170, margin: 12, borderRadius: 10, }, text: { color: "white", fontSize: 20, fontWeight: "bold", textAlign: "center", backgroundColor: "#000", }, });
适配说明:
如果接口返回的item没有id字段,可以改用index作为标识:
- 在
renderItem中解构出index:renderItem={({ item, index }) => (...) - 点击事件改成:
onPress={() => setActiveItemId(activeItemId === index ? null : index)} - 显示条件改成:
{activeItemId === index && <Text style={styles.text}>{item.name}</Text>}
这种方式保证每个列表项的显示状态独立,点击某一项只会影响自身的文本显示/隐藏。
内容的提问来源于stack exchange,提问作者Jason0011
相关产品推荐
相关产品推荐

