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

React Native:点击TouchableOpacity按钮无法更新Text内容的问题

解决React Native中TouchableOpacity点击后Text内容不更新的问题

问题根源分析

你的代码存在三个核心问题导致Text内容无法更新:

  • 普通变量无法触发组件重渲染:用let content = '...'声明的变量不是React状态,React不会追踪它的变化,就算修改了值,组件也不会重新渲染,Text始终显示初始值。
  • Action逻辑错误:部分选项的action用了全等判断content === options.title(这只是比较操作,不是赋值),而且所有action里的options.title都是错误的(应该是当前选项的op.title,而非整个数组的title)。
  • 点击选项后未关闭弹窗:缺少点击选项后关闭弹窗的逻辑,影响交互体验。

修复后的完整代码

import React, { useState, useRef } from 'react';
import { TouchableOpacity, Text, Modal, SafeAreaView, Animated, Easing } from 'react-native';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
// 请确保style和layouts已正确导入

const PopupMenuSelect = () => {
    const [visible, setVisible] = useState(false);
    const [content, setContent] = useState('...'); // 改用useState管理内容状态
    const scale = useRef(new Animated.Value(0)).current;
    
    // 优化:去掉重复的action定义,统一在渲染时处理
    const options = [
        { title: 'Spotify', icon: 'spotify' },
        { title: 'Yammer', icon: 'yammer' },
        { title: 'Trello', icon: 'trello' },
        { title: 'Twitter', icon: 'twitter' },
        { title: 'Discord', icon: 'discord' },
        { title: 'Outlook', icon: 'mail-bulk' },
    ];

    function resizeBox(to){
        to === 1 && setVisible(true);
        Animated.timing(scale,{
            toValue: to,
            useNativeDriver: true,
            duration: 200,
            easing: Easing.linear,
        }).start(() => to === 0 && setVisible(false));
    }

    return (
        <>
            <TouchableOpacity onPress={() => resizeBox(1)}>
                <Text style={[style.subtext, { color: layouts.secondary }]}>{content}</Text>
            </TouchableOpacity>
            <Modal transparent visible={visible}>
                <SafeAreaView style={{ flex: 1 }} onTouchStart={() => resizeBox(0)}>
                    <Animated.View 
                        style={[
                            style.popUp,
                            { opacity: scale.interpolate({ inputRange: [0, 1], outputRange:[0, 1]}) },
                            { transform: [{ scale }]},
                        ]}
                    >
                        {options.map((op, i) => (
                            <TouchableOpacity 
                                style={[style.option, { borderBottomWidth: i === options.length - 1 ? 0 : 1 }]} 
                                key={i} 
                                onPress={() => {
                                    setContent(op.title);
                                    resizeBox(0);
                                }}
                            >
                                <Text style={{fontFamily: "Title-Font", fontSize: 15}}>{op.title}</Text>
                                <FontAwesome5 name={op.icon} size={26} color={'black'} style={{marginLeft: 10}}/>
                            </TouchableOpacity>
                        ))}
                    </Animated.View>
                </SafeAreaView>
            </Modal>
        </>
    )
}

export default PopupMenuSelect;

关键修改说明

  1. 用useState管理content:把let content = '...'改成const [content, setContent] = useState('...'),这样每次调用setContent时,React会触发组件重渲染,Text会显示最新值。
  2. 统一处理点击逻辑:去掉options里冗余的action定义,直接在TouchableOpacity的onPress中完成赋值和弹窗关闭操作,避免重复代码和逻辑错误。
  3. 修复选项赋值逻辑:直接使用当前循环项的op.title给content赋值,确保内容对应正确的选项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:20:27