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

React Native动态列表中onPress悬停效果异常问题求助

修复方案:列表中点击单张图片仅显示对应文本

你遇到的问题根源是全局布尔状态showText被所有列表项共享,点击任何一项都会切换这个全局状态,导致所有图片的文本同时显示/隐藏。解决思路是用「记录当前激活项的唯一标识」替代全局布尔值,让每个列表项只判断自己是否是激活项。

修改步骤:

  1. 替换状态定义:把全局布尔状态改成记录激活项ID(或索引)的状态
  2. 更新点击逻辑:点击时切换当前激活项(如果点击的是已激活项则取消激活)
  3. 调整文本显示条件:仅当当前项是激活项时显示文本

修改后的完整代码

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作为标识:

  1. 在renderItem中解构出index:renderItem={({ item, index }) => (...)
  2. 点击事件改成:onPress={() => setActiveItemId(activeItemId === index ? null : index)}
  3. 显示条件改成:{activeItemId === index && <Text style={styles.text}>{item.name}</Text>}

这种方式保证每个列表项的显示状态独立,点击某一项只会影响自身的文本显示/隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:05:32