React Native Expo 应用程序:尽管路径和样式正确,本地图像仍不显示

问题描述 投票:0回答:1

我在 React Native Expo 应用程序中遇到一个问题,尽管应用了正确的路径和样式,但存储在资产目录中的本地图像未显示。我尝试过使用不同的 PNG 格式的图像,验证了资源中存储的照片的直接 URL,并确保每个路径都是准确的。但是,仅显示具有外部链接的非本地图像(例如存储在网络上的图像)。

我已尝试各种故障排除步骤来解决此问题:

Checked the paths of the images in the assets directory to ensure they are correct.
Verified the image formats (PNG) and attempted using different images to rule out any specific image-related issues.
Confirmed that the styles applied to the image components are correct and that the container view shows the space allocated for the image.
Verified that the images are properly imported and referenced in the source attribute of the Image component.

尽管如此,本地图像仍然无法显示。我希望图像能够在应用程序中正确呈现,就像使用带有外部链接的非本地图像时一样。

任何人都可以帮我解决这个问题并提出潜在的解决方案吗?任何见解或建议将不胜感激。谢谢!

我的配置:

react-native-cli:2.0.1 反应本机:0.72.12 展会SDK版本:49.0.0

这是我的文件示例,其中包含我想要显示的图像:

import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, TextInput, KeyboardAvoidingView, SafeAreaView, Image } from 'react-native'
import { useDispatch } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import { login } from '../store/reducers/user'
import AuthAPI from '../services/authAPI'
import FontAwesome from 'react-native-vector-icons/FontAwesome'
import AsyncStorage from '@react-native-async-storage/async-storage';

// Custom input component
const CustomInput = ({ icon, placeholder, onChangeText, value, secureTextEntry, error, onFocus, onBlur }) => {
  return (
    <View style={styles.inputContainer}>
      <FontAwesome name={icon} style={styles.icon} />
      <TextInput
        placeholder={placeholder}
        onChangeText={onChangeText}
        value={value}
        secureTextEntry={secureTextEntry}
        style={styles.input}
        onFocus={onFocus}
        onBlur={onBlur}
      />
      {error && <Text style={styles.error}>{error}</Text>}
    </View>
  );
};

function SigninScreen({ setIsLoggedIn}) {
  const dispatch = useDispatch(); 

  const [signinEmail, setSigninEmail] = useState("");
  const [signinPassword, setSigninPassword] = useState("");
  const [errors, setErrors] = useState({}); // State to store errors
  const navigation = useNavigation();

  const handleInputFocus = () => {
    // Clear errors when input is focused
    setErrors({});
  };

  const handleSignin = async () => {
    // Validation logic
    const errors = {};
    if (!signinEmail.trim()) {
      errors.email = "L'email est requis";
    }
    if (!signinPassword.trim()) {
      errors.password = "Le mot de passe est requis";
    }

    // Si des erreurs sont détectées, arrêtez le processus de connexion
    if (Object.keys(errors).length > 0) {
      setErrors(errors);
      return;
    }

    try {
      // Data in json
      const data = await AuthAPI.signin({ password: signinPassword, email: signinEmail });

      if (data.result) {
        dispatch(login({
          token: data.token,
          email: signinEmail
        }))
        AsyncStorage.setItem('token', data.token)
        AsyncStorage.setItem('isLoggedIn', JSON.stringify(true));
        setIsLoggedIn(true);
        setSigninEmail("");
        setSigninPassword("");
        
      } else {
        alert("Mauvais email ou mot de passe");
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <SafeAreaView>
      <KeyboardAvoidingView style={styles.main}>
        <Text style={styles.title}>Sign In</Text>
        <View style={styles.logoContainer}>
          <Image style={styles.logo} source={require('../assets/logo_em.png')} />
        </View>
        <View style={styles.form}> 
          <CustomInput
            icon="user-o"
            placeholder="Email"
            onChangeText={(value) => setSigninEmail(value)}
            value={signinEmail}
            error={errors.email} // Pass error message to custom input
            onFocus={handleInputFocus} // Clear errors when input is focused
          />
          <CustomInput
            icon="lock"
            placeholder="Password"
            secureTextEntry={true}
            onChangeText={(value) => setSigninPassword(value)}
            value={signinPassword}
            error={errors.password}
            onFocus={handleInputFocus} // Clear errors when input is focused
          />
          <TouchableOpacity style={{ marginBottom: 6, marginTop: -5 }}>
            <Text style={{ fontWeight: 'bold', marginLeft: '40%' }}>Forgot your password ?</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button} onPress={handleSignin}>
            <Text style={styles.buttonText}>Sign In</Text>
          </TouchableOpacity>
          <Text style={{ fontWeight: 'bold', marginBottom: 5 }}>Don't have an account yet ? </Text>
          <TouchableOpacity style={styles.button2} onPress={() => navigation.navigate("Signup")}>
            <Text style={styles.buttonText2}>Sign Up</Text>
          </TouchableOpacity>
        </View>

      </KeyboardAvoidingView>

    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  main: {
    width: '100%',
    height: '100%',
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    color: 'black',
    textAlign: 'center',
    fontSize: 30,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  logoContainer: {
    flex:1
  },
  logo: {
    width: 50,
    height: 50,
  },
  form: {
    width: '80%',
    alignItems: 'center'
  },
  inputContainer: {
    position: 'relative',
    marginBottom: 10,
    width: '100%',
  },
  icon: {
    position: 'absolute',
    fontSize: 20,
    color: 'black',
    zIndex: 1,
    left: 10,
    top: 13,
  },
  input: {
    backgroundColor: "white",
    borderWidth: 1,
    borderColor: "black",
    borderRadius: 10,
    padding: 10,
    width: '100%',
    paddingLeft: 40, // Adjusted for icon width and position
  },
  button: {
    backgroundColor: 'black',
    borderRadius: 10,
    padding: 10,
    marginBottom: 10,
    width: '100%',
    alignItems: 'center',
    marginTop: '5%'
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  button2: {
    borderRadius: 10,
    padding: 10,
    marginBottom: 10,
    borderWidth: 1,
    borderColor: 'black',
    width: '100%',
    alignItems: 'center',
  },
  buttonText2: {
    color: 'black',
  },
  error: {
    color: 'red',
    marginTop: 5,
    textAlign: 'center', // Center the error message
  },
});

export default SigninScreen;

这是我的项目结构的快照:

project snapshot

react-native image expo asset-management
1个回答
0
投票

我通常使用单独维护的资产目录来管理静态资产,因此我不必为每个图像组件创建绝对路径。这还允许您在博览会中动态使用图像。

例如,在

images.js
文件夹中创建一个
assets
文件。然后为所有图像创建单一路径。对于您的项目,此代码将如下所示:

//images.js

const icon = require('./icon.png')
const logo = require('./logo_em.png')

export default{
icon,
logo
};

然后只需将此文件导入到您需要使用图像组件的应用程序的其余部分即可。这看起来像这样:

//SigninScreen.js

import images from "../assets/images";

...

<Image style={styles.logo} source={images.logo} />

这有助于组织您的代码并保持目录干净。它还将所有资源加载到一个位置,从而允许在应用程序捆绑期间显式定义它们。

您可以尝试执行此操作,但我不确定您的问题来自何处。 sdk 49 和 50 过去曾出现过在上传本地文件时造成重大更改的问题。有时,不推荐使用的依赖项会导致此问题。检查您的依赖关系并考虑更新。您可以在此处找到更多相关信息。

我最近不得不这样做,并陷入依赖地狱大约一个小时左右。我发现同时使用

"react-native": "0.73.4"
"expo": "^50.0.7"
"eas-cli": "^0.49.0"
对我很有用。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.