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

React Native中使用Hook状态切换Image图片失败的问题排查

问题分析与修复方案

错误原因

  1. 本地图片引入方式错误:React Native中本地图片必须通过require()加载,直接使用字符串路径无法被组件识别。你的imagens对象里仅存储了字符串路径,没有用require()包裹。
  2. useEffect无限循环:当前的useEffect没有指定依赖数组,会在组件每次渲染时触发,导致setSkin反复执行,引发不必要的状态更新。
  3. Image组件source参数格式错误:source需要接收require()返回的资源对象,而不是单纯的字符串,所以直接传skin或未处理的imagens[skin]都无法正常显示图片。

修复后的完整代码

import React, { useState, useEffect } from 'react';
import { SafeAreaView, TouchableOpacity, Image, Pressable, View, Text } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import BottomSheet from './BottomSheet';
import barrinhaLoja from '../assets/barrinhaLoja.png';
import vovoJuju from '../assets/vovoJuju.png';
import mcJuju from '../assets/mcJuju.png';
import patoJuju from '../assets/patoJuju.png';
import styles from './styles';

export function Home(){
    // 修正:用require包裹本地图片路径
    const imagens = {
        vovo: require('../assets/vovoJuju.png'),
        mc: require('../assets/mcJuju.png'),
        pato: require('../assets/patoJuju.png'),
    }
    const navigation = useNavigation<any>();
    const [showBottomSheet, setShowBottomSheet] = useState(false);
    const [param, setParam] = useState(1);
    const [skin, setSkin] = useState('vovo')

    const hide = () => {
        setShowBottomSheet(false)
    }

    function handleAbout(){
        navigation.navigate('About');
    }
    
    // 修正:添加依赖数组[param],仅当param变化时执行
    useEffect(() => {
        if(param === 1){
            setSkin('vovo');
        } else if(param === 2){
            setSkin('mc');
        } else if(param === 3){
            setSkin('pato');
        }
    }, [param])
 
    return(
        <SafeAreaView style={styles.container}>
            <TouchableOpacity onPress={handleAbout}>
                <Counter />
            </TouchableOpacity>
            
            <TouchableOpacity onPress={() => setShowBottomSheet(true)}>
                {/* 修正:传入imagens[skin],即require后的资源对象 */}
                <Image source={imagens[skin]} style={styles.imgvj}/>
            </TouchableOpacity>

            <BottomSheet show={showBottomSheet} height={290} onOuterClick={hide}>
                <Pressable onPress={hide} style={styles.bottomSheetContent}>
                    <Image source={barrinhaLoja} style={styles.barra}/>
                </Pressable>
                <View style={styles.conteudoLoja}>
                    <View style={styles.marginLeft48}>
                        <TouchableOpacity onPress={() => {
                            setParam(1);
                            hide();
                        }}>
                            <Image source={vovoJuju} style={styles.vovo}/>
                            <Text style={styles.legendasLoja}>Vovó Juju</Text>
                        </TouchableOpacity>
                    </View>

                    <View>
                        <TouchableOpacity onPress={() => {
                            setParam(2);
                            hide();
                        }}>
                            <Image source={mcJuju} style={styles.mc}/>
                            <Text style={styles.legendasLoja}>MC Juju</Text>
                        </TouchableOpacity>
                    </View>
                    
                    <View>
                        <TouchableOpacity onPress={() => {
                            setParam(3);
                            hide();
                        }}>
                            <Image source={patoJuju} style={styles.pato}/>
                            <Text style={styles.legendasLoja}>Pato Juju</Text>
                        </TouchableOpacity>
                    </View>
                </View>
            </BottomSheet>
        </SafeAreaView>
    )
}

可选优化:减少冗余状态

可以直接去掉param状态,在点击选项时直接设置skin,省去useEffect的逻辑:

// 移除param状态和对应的useEffect
// 修改弹窗内的TouchableOpacity:
<TouchableOpacity onPress={() => {
    setSkin('vovo');
    hide();
}}>

这样代码更简洁,避免了中间状态的流转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:50:29