【问题标题】:React Native - Image Require Module using Dynamic NamesReact Native - 使用动态名称的图像需要模块
【发布时间】:2022-01-03 09:06:25
【问题描述】:

我目前正在使用 React Native 构建一个测试应用程序。 Image 模块到目前为止运行良好。

例如,如果我有一个名为 avatar 的图像,则以下代码 sn-p 可以正常工作。

<Image source={require('image!avatar')} />

但是如果我把它改成动态字符串,我会得到

<Image source={require('image!' + 'avatar')} />

我得到错误:

需要未知模块“image!avatar”。如果您确定该模块在那里,请尝试重新启动打包程序。

显然,这是一个人为的示例,但动态图像名称很重要。 React Native 不支持动态图片名称吗?

【问题讨论】:

标签: javascript react-native jsx


【解决方案1】:

这在“Static Resources”部分的文档中有所介绍:

在包中引用图像的唯一允许方法是在源代码中逐字写入 require('image!name-of-the-asset')。

// GOOD
<Image source={require('image!my-icon')} />

// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('image!' + icon)} />

// GOOD
var icon = this.props.active ? require('image!my-icon-active') : require('image!my-icon-inactive');
<Image source={icon} />

但是,您还需要记住在 Xcode 中将图像添加到应用程序中的 xcassets 包中,尽管从您的评论看来您已经这样做了。

http://facebook.github.io/react-native/docs/image.html#adding-static-resources-to-your-app-using-images-xcassets

【讨论】:

  • 我应该在哪里添加图片,我正在使用 react native for android,在 drawable 文件夹中?
  • 上面的链接不对,文章现在在facebook.github.io/react-native/docs/images.html
  • 你好,如果我需要数百张图片怎么办?
  • @chanjianyi 我也有同样的情况:-(
  • "Require" 不适用于我的 IOS 设备。知道为什么吗?
【解决方案2】:

如果您的文件数量较多,这里有一个简单且真正动态的解决方案。

[不适用于 Expo Managed]

虽然这个问题很老,但我认为这是更简单的解决方案,可能会有所帮助。但请原谅任何术语错误,如果我有任何错误,请纠正我。

除了使用 REQUIRE,我们可以将 URINative APP Assets 一起用于 ANDROID(和/或 iOS)。 这里我们只讨论安卓

URI 可以根据要求轻松操作,但通常仅用于网络/远程资产,但也适用于本地和本机资产。而 require 不能用于动态文件名和目录

步骤

  1. 从您的App.jsindex.js 包含目录打开android/app/src/main/assets 文件夹,如果assets 文件夹不存在,请创建一个。
  2. assets 中创建一个名为images 或您选择的任何NAME 的文件夹,然后将所有图像粘贴到那里。
  3. 在包含App.jsindex.js 的主应用文件夹中创建一个名为react-native.config.js 的文件。
  4. 将这些行添加到新的 js 文件中:

module.exports = {
  project: {
    ios: {},
    android: {},
  },
  assets: ['./assets/YOUR_FOLDER_NAME/'],
};

YOUR_FOLDER_NAME 的位置使用新创建的文件夹名称images 或任何给定的NAME

  1. 现在在您的终端中从主应用程序文件夹运行npx react-native link,这将链接/添加 android 包中的资产文件夹。然后重建调试应用。
  2. 从现在开始,您可以在您的 react-native 应用程序中访问 android/app/src/main/assets 内部的所有文件。 例如:
<Image
   style={styles.ImageStyle}
   source={{ uri: 'asset:/YOUR_FOLDER_NAME/img' + Math.floor(Math.random() * 100) + '.png' }}
/>

【讨论】:

    【解决方案3】:

    如果您正在寻找一种方法来创建一个列表,例如通过循环浏览图像和描述的 JSON 数组,这将适合您。

    1. 创建一个文件(保存我们的 JSON 数据库),例如 ProfilesDB.js:

    const Profiles = [
      {
        id: '1',
        name: 'Peter Parker',
        src: require('../images/user1.png'),
        age: '70',
      },
      {
        id: '2',
        name: 'Barack Obama',
        src: require('../images/user2.png'),
        age: '19',
      },
      {
        id: '3',
        name: 'Hilary Clinton',
        src: require('../images/user3.png'),
        age: '50',
      },
    ];
    
    export default Profiles;
    1. 然后在我们的组件中导入数据并使用 FlatList 循环遍历列表:

    import Profiles from './ProfilesDB.js';
    
    <FlatList
      data={Profiles}
      keyExtractor={(item, index) => item.id}
      renderItem={({item}) => (
        <View>
          <Image source={item.src} />
          <Text>{item.name}</Text>
        </View>
      )}
    />

    祝你好运!

    【讨论】:

    • 这正是我想要的。我正在我的应用程序中创建一个本地“数据”文件,我需要访问这些图像。我试过 但它没有用,所以在尝试了你提供的解决方案后它对我有用。谢谢!
    • 如果有更多的图像文件,那么实现它的逻辑是什么?我无法为所有这 50 张图像手动编写代码。我能够列出所有图像并导出所有图像,但它是节点 js 代码。
    • @CrackerKSR,你是对的。此解决方案通常最适合少数图像。
    【解决方案4】:

    在保存图片路径的地方创建一个常量,包括 require,然后在源代码中输入该常量的名称。

    const image = condition ? require("../img/image1.png") : require('../img/image2.png');
    
    <Image source={image} />
    

    【讨论】:

      【解决方案5】:

      如果您有一个与我的功能相似的应用程序。您的应用程序大部分处于离线状态,并且您希望一个接一个地渲染图像。然后下面是在 React Native 0.60 版中对我有用的方法。

      1. 首先创建一个名为 Resources/Images 的文件夹,然后将所有图片放在那里。
      2. 现在创建一个名为 Index.js 的文件(位于 Resources/Images),该文件负责索引 Resources/Images 文件夹中的所有图像。

      常量图像 = { 'image1': 需要('./1.png'), 'image2': 需要('./2.png'), 'image3':需要('./3.png') }

      1. 现在在您选择的文件夹中创建一个名为 ImageView 的组件。可以创建函数式、类或常量组件。我使用了 Const 组件。该文件负责根据索引返回图片。
      import React from 'react';
      import { Image, Dimensions } from 'react-native';
      import Images from './Index';
      const ImageView = ({ index }) => {
          return (
              <Image
                  source={Images['image' + index]}
              />
          )
      }
      export default ImageView;
      
      1. 现在,无论您想要动态呈现静态图像的任何位置,只需使用 ImageView 组件并传递索引即可。

      【讨论】:

        【解决方案6】:

        使用require来动态图片

        this.state={
               //defualt image
               newimage: require('../../../src/assets/group/kids_room3.png'),
               randomImages=[
                 {
                    image:require('../../../src/assets/group/kids_room1.png')
                  },
                 {
                    image:require('../../../src/assets/group/kids_room2.png')
                  }
                ,
                 {
                    image:require('../../../src/assets/group/kids_room3.png')
                  }
                
                
                ]
        
        }
        

        按下按钮时-(我选择0-2之间的图像随机数))

        let setImage=>(){
        //set new dynamic image 
        this.setState({newimage:this.state.randomImages[Math.floor(Math.random() * 3)];
        })
        }
        

        查看

        <Image
                style={{  width: 30, height: 30 ,zIndex: 500 }}
                
                source={this.state.newimage}
              />
        

        【讨论】:

          【解决方案7】:

          首先,创建一个需要图像的文件 - 必须以这种方式加载 React 原生图像。

          资产/index.js

          export const friendsandfoe = require('./friends-and-foe.png'); 
          export const lifeanddeath = require('./life-and-death.png'); 
          export const homeandgarden = require('./home-and-garden.png');
          

          现在导入您的所有资产

          App.js

          import * as All  from '../../assets';
          

          您现在可以将图像用作插值值,其中 imageValue(来自后端)与命名的本地文件相同,即:'homeandgarden':

          <Image style={styles.image} source={All[`${imageValue}`]}></Image>
          

          【讨论】:

          • 别担心!在这里找不到一个好的解决方案,所以想出了我自己的一个:) 很高兴能提供帮助。
          【解决方案8】:

          作为React Native Documentation says,在编译你的包之前需要加载你所有的图像源

          所以另一种使用动态图像的方法是使用 switch 语句。假设你想为不同的角色显示不同的头像,你可以这样做:

          class App extends Component {
            state = { avatar: "" }
          
            get avatarImage() {
              switch (this.state.avatar) {
                case "spiderman":
                  return require('./spiderman.png');
                case "batman":
                  return require('./batman.png');
                case "hulk":
                  return require('./hulk.png');
                default:
                  return require('./no-image.png');
              }
            }
          
            render() {
              return <Image source={this.avatarImage} />
            }
          }
          

          查看零食:https://snack.expo.io/@abranhe/dynamic-images

          另外,请记住,如果您的图片在线,您没有任何问题,您可以这样做:

          let superhero = "spiderman";
          
          <Image source={{ uri: `https://some-website.online/${superhero}.png` }} />
          

          【讨论】:

            【解决方案9】:
            import React, { Component } from 'react';
            import { Image } from 'react-native';
            
            class Images extends Component {
              constructor(props) {
                super(props);
                this.state = {
                       images: {
                            './assets/RetailerLogo/1.jpg': require('../../../assets/RetailerLogo/1.jpg'),
                            './assets/RetailerLogo/2.jpg': require('../../../assets/RetailerLogo/2.jpg'),
                            './assets/RetailerLogo/3.jpg': require('../../../assets/RetailerLogo/3.jpg')
                        }
                }
              }
            
              render() {
                const {  images } = this.state 
                return (
                  <View>
                    <Image
                                        resizeMode="contain"
                                        source={ images['assets/RetailerLogo/1.jpg'] }
                                        style={styles.itemImg}
                                    />
                 </View>
              )}
            }
            

            【讨论】:

              【解决方案10】:

              这里的重要部分: 我们不能像 [require('item'+vairable+'.png')] 那样在 require 中连接图像名称

              第 1 步:我们创建一个 ImageCollection.js 文件,其中包含以下图像属性集合

              ImageCollection.js
              ================================
              export default images={
                  "1": require("./item1.png"),
                  "2": require("./item2.png"),
                  "3": require("./item3.png"),
                  "4": require("./item4.png"),
                  "5": require("./item5.png")
              }
              

              第 2 步:在您的应用中导入图像并根据需要进行操作

              class ListRepoApp extends Component {
              
                  renderItem = ({item }) => (
                      <View style={styles.item}>
                          <Text>Item number :{item}</Text>
                          <Image source={Images[item]}/>
                      </View>
                  );
              
                  render () {
                      const data = ["1","2","3","4","5"]
                      return (
                          <FlatList data={data} renderItem={this.renderItem}/>
                      )
                  }
              }
              
              export default ListRepoApp;
              

              如果您需要详细说明,可以点击以下链接 访问https://www.thelearninguy.com/react-native-require-image-using-dynamic-names

              礼貌:https://www.thelearninguy.com

              【讨论】:

                【解决方案11】:
                 <StyledInput text="NAME" imgUri={require('../assets/userIcon.png')} ></StyledInput> 
                
                <Image
                            source={this.props.imgUri}
                            style={{
                              height: 30,
                              width: 30,
                              resizeMode: 'contain',
                            }}
                          />   
                

                在我的情况下,我尝试了很多,但最终成功了 StyledInput 组件名称 如果您仍然不明白,请告诉我 StyledInput 中的图像

                【讨论】:

                  【解决方案12】:

                  这对我有用:

                  我制作了一个自定义图像组件,它接受一个布尔值来检查图像是来自网络还是从本地文件夹传递。

                  // In index.ios.js after importing the component
                  <CustomImage fromWeb={false} imageName={require('./images/logo.png')}/>
                  
                  // In CustomImage.js which is my image component
                  <Image style={styles.image} source={this.props.imageName} />
                  

                  如果您看到代码,请不要使用以下代码之一:

                  // NOTE: Neither of these will work
                  source={require('../images/'+imageName)} 
                  var imageName = require('../images/'+imageName)
                  

                  我只是将整个require('./images/logo.png') 作为道具发送。 有效!

                  【讨论】:

                  • 这个答案更值得称赞。当您声明 require 语句并作为道具传递时,它绝对有效。非常感谢您的简单解释,我只希望其他人也一样清楚。
                  • 道具的作用很神奇。这应该在官方文档中说明。
                  • class CustomImage extends Component { constructor(props) { super(props); } render() { return ( &lt;Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /&gt; ); } } &lt;CustomImage fromWeb={false} imageName={require(`../../images/phone-${item.status}.png`)} /&gt;
                  • 在父组件中我有&lt;CustomImage fromWeb={false} imageName={require(../../assets/icons/${el.img}.png)} /&gt; 和这个在子组件class CustomImage extends Component { constructor(props) { super(props); } render() { return ( &lt;Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /&gt; ); } }
                  • 纯粹的天才,这正是我正在寻找的:)
                  【解决方案13】:

                  我知道这是旧的,但我将在此处添加它,因为我发现了这个问题,同时寻找解决方案。文档允许使用 uri:'Network Image'

                  https://facebook.github.io/react-native/docs/images#network-images

                  对我来说,我得到了动态工作的图像

                  <Image source={{uri: image}} />
                  

                  【讨论】:

                    【解决方案14】:

                    如果您知道图像 (URL),则相关:

                    我破解这个问题的方法:

                    我创建了一个文件,其中包含一个存储图像和图像名称的对象:

                    const images = {
                      dog: {
                        imgName: 'Dog', 
                        uri: require('path/to/local/image')
                      },
                      cat: {
                        imgName: 'Cat on a Boat', 
                        uri: require('path/to/local/image')
                      }
                    }
                    
                    export { images };
                    

                    然后我将对象导入到我想使用它的组件中,然后像这样进行条件渲染:

                    import { images } from 'relative/path';
                    
                    if (cond === 'cat') {
                      let imgSource = images.cat.uri;
                    }
                    
                    <Image source={imgSource} />
                    

                    我知道这不是最有效的方法,但绝对是一种解决方法。

                    希望对你有帮助!

                    【讨论】:

                    • 处理一组已知图像的简洁解决方案
                    • @WalterMonecke:如果我们这样做,我会得到整数值
                    【解决方案15】:

                    你可以使用

                    <Image source={{uri: 'imagename'}} style={{width: 40, height: 40}} />
                    

                    显示图像。

                    来自:

                    https://facebook.github.io/react-native/docs/images.html#images-from-hybrid-app-s-resources

                    【讨论】:

                      【解决方案16】:

                      你应该为此使用一个对象。

                      例如,假设我向 API 发出了 AJAX 请求,它返回了一个图片链接,我将保存为imageLink

                      source={{uri: this.state.imageLink}}

                      【讨论】:

                      • 对于动态图片路径链接,这不起作用:var img = "../img/icons/"+img_name+"_selected.png"; &lt;br/&gt; &lt;Image source={{uri: img}} resizeMode={'contain'} /&gt;
                      • 一个 hack,如果你知道所有的 img_name 变体都会这样:var images = { 'first': require('../first.png'), 'second': require('../second.png') } &lt;Image source={{uri:images[img_name]}} resizeMode={'contain'} /&gt;
                      • 请注意@GabrielLupu 的建议:您正在通过这种方式分配内存中的所有图像。这取决于图像的数量及其大小,但是您可能会遇到内存不足错误。
                      猜你喜欢
                      • 2017-04-03
                      • 2016-06-22
                      • 1970-01-01
                      • 2016-01-13
                      • 1970-01-01
                      • 2016-05-25
                      • 2015-06-01
                      相关资源
                      最近更新 更多