为图像文件react本机使用变量

IT技术 javascript ios react-native
2021-01-14 23:38:25

我知道要在 React Native 中使用静态图像,您需要专门对该图像进行要求,但我正在尝试根据数字加载随机图像。例如,我的目录中有 100 张名为 img1.png - img100.png 的图像。我试图找出一种方法来执行以下操作

<Image source={require(`./img${Math.floor(Math.random() * 100)}.png`)}/>

我知道这故意不起作用,但任何解决方法将不胜感激。

5个回答

对于任何了解 react-native 野兽的人来说,这应该会有所帮助:)

我过去也访问过几个网站,但发现它越来越令人沮丧。直到我在这里阅读了这个网站

这是一种不同的方法,但最终确实得到了回报。基本上,最好的方法是将所有资源加载到一个地方。考虑以下结构

app  
   |--img
      |--image1.jpg
      |--image2.jpg
      |--profile
          |--profile.png
          |--comments.png
      |--index.js

在 中index.js,您可以这样做:

const images = {
    profile: {
        profile: require('./profile/profile.png'),
        comments: require('./profile/comments.png'),
    },
    image1: require('./image1.jpg'),
    image2: require('./image2.jpg'),
};

export default images;

在您的视图中,您必须像这样导入图像组件:

import Images from './img/index';

render() {
    <Image source={Images.profile.comments} />
}

每个人都有不同的方法达到目的,选择最适合你的方法。

Da Man - 问:这个答案如何使用变量?

好吧,由于require只接受文字字符串,所以不能使用变量、连接字符串等。这是下一个最好的事情。是的,它仍然有很多工作,但现在你可以做一些类似于 OP 问题的事情:

render() {
  var images = { test100: "image100" };
  return (
    <View>
      <Text>
       test {images["test" + "100"]}
      </Text>
    </View>
  );
}
@Aaron 不,加载和渲染之间存在差异。这些图像仅在您使用它们时才会呈现(称为延迟加载)。将此视为一袋钩子。实际渲染发生在这里:<Image source={Images.profile.comments} />
2021-03-14 23:38:25
这种方法如何使用变量?您仍在指定要加载的图像。
2021-03-16 23:38:25
只是好奇,这是否意味着当用户点击视图时每个图像都会加载到内存中,并且每次都会发生这种情况?
2021-03-18 23:38:25
太感谢了!
2021-03-30 23:38:25
@bubble-cord 您是在谈论诸如“test 001”之类的键吗?在这种情况下; 是的。{"test 001": "<imgurl>"}是一个有效的 js 对象,因此正在使用images["test 001"]
2021-03-31 23:38:25

在 JS 中 require 语句在捆绑时解析(当计算 JS 捆绑时)。因此,不支持将变量表达式作为require.

如果需要资源,那就更棘手了。当您拥有 时require('./someimage.png'),React Native 打包器将对所需图像进行本地化,然后将其与应用程序捆绑在一起,以便在您的应用程序运行时将其用作“静态”资源(实际上在开发模式下它不会捆绑图像与您的应用程序,但图像将从服务器提供,但这对您的情况无关紧要)。

如果您想使用随机图像作为静态资源,您需要告诉您的应用程序捆绑该图像。您可以通过以下几种方式做到这一点:

1) 将其添加为应用程序的静态资产,然后使用<Image src={{uri:'name_of_the_image_in_assets.png'}}/>这里是如何将其添加到本机 iOS 应用程序)引用它

2) 预先静态要求所有图像。某种形式的:

var randomImages = [
    require('./image1.png'),
    require('./image2.png'),
    require('./image3.png'),
    ...
];

然后在您的代码中,您可以执行以下操作:

<Image src={randomImages[Math.floor(Math.random()*randomImages.length)]}/>

3)使用网络图像 <Image src={{uri:'http://i.imgur.com/random.jpg'}}/>

如果列表来自 api 怎么办?
2021-03-14 23:38:25
这为我解决了我的问题。我试图在函数中动态创建链接,并将 require(<variablePath>) 返回到图像源,并且不断出现错误。做得好!
2021-03-28 23:38:25
如果您有一千张名为 image1.png、image2.png、image3.png 等的图像 - 看起来很奇怪 require 不接受可变路径并且您无法编写循环来创建该 randomImages 数组。不是要被迫写一千行吗?!如果我尝试将变量传递到 require 行,它会抱怨找不到module。
2021-04-08 23:38:25
class ImageContainer extends Component {
   this.state ={
     image:require('default-img')
   }
    <View>
           <Image source={this.state.image} />
    </View>
}

在本次讨论的上下文中,我遇到过想要为特定背景动态分配图像的情况。在这里,我像这样改变状态

this.setState({
  image:require('new-image')
})
require 中的文本可以交换 state 或 props,注意上面例子的目的是为了检索本地图像,对于外部图像,即“ image.png ”,语法结构将更改为 <Image source={{ uri :外部图像}}>
2021-03-16 23:38:25
在require里面,如果我必须使用动态图像那么怎么做?例如: image:require(this.index+".png") 其中 index = 1 最初。
2021-03-29 23:38:25
这是一个好的开始。你能补充一下它是如何解决问题的吗?对您的代码所做的事情进行一些描述会很好。
2021-03-31 23:38:25

我来到这个线程寻找一种以动态方式添加图像的方法。我很快发现将变量传递给 Image -> require() 不起作用。

感谢 DerpyNerd 让我走上正确的道路。

在一个地方实现资源后,我发现添加图像很容易。但是,我仍然需要一种方法来根据应用程序中不断变化的状态动态分配这些图像。

我创建了一个函数,它接受来自状态值的字符串,然后返回逻辑上匹配该字符串的图像。

设置

图像结构:

app  
  |--src
    |--assets
      |--images
        |--logos
          |--small_kl_logo.png
          |--small_a1_logo.png
          |--small_kc_logo.png
          |--small_nv_logo.png
          |--small_other_logo.png

        |--index.js
    |--SearchableList.js

index.js,我有这个:

const images = {
  logos: {
    kl: require('./logos/small_kl_logo.png'),
    a1: require('./logos/small_a1_logo.png'),
    kc: require('./logos/small_kc_logo.png'),
    nv: require('./logos/small_nv_logo.png'),
    other: require('./logos/small_other_logo.png'),
  }
};

export default images;

在我的SearchableList.js组件中,我然后像这样导入了 Images 组件:

import Images from './assets/images';

然后imageSelect我在我的组件中创建了一个新函数

imageSelect = network => {
  if (network === null) {
    return Images.logos.other;
  }

  const networkArray = {
    'KL': Images.logos.kl,
    'A1': Images.logos.a1,
    'KC': Images.logos.kc,
    'NV': Images.logos.nv,
    'Other': Images.logos.other,
  };

  return networkArray[network];
};

然后在我的组件render函数中,我调用这个新imageSelect函数来根据 中的值动态分配所需的图像this.state.network

render() {
  <Image source={this.imageSelect(this.state.network)} />
}

再次感谢 DerpyNerd 让我走上了正确的道路。我希望这个答案可以帮助其他人。:)

我认为你在这里把事情复杂化了。不需要该imageSelect功能。因为images是一个简单的 javascript 对象,您可以动态调用该对象中的键。例如<Image source={Images.logos[this.state.network]} />只要确保它们的密钥与可能的网络状态匹配:)
2021-04-11 23:38:25

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

[不适用于世博会管理]

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

我们可以将URIAndroid(和/或 iOS)的原生应用资产一起使用,而不是使用REQUIRE这里我们只讨论安卓

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

脚步

  1. android/app/src/main/assets从您的目录App.jsindex.js 包含目录中打开文件夹,如果该assets文件夹不存在,请创建一个。
  2. 在 中创建一个名为images或任何NAME您选择的文件夹assets,然后将所有图像粘贴到那里。
  3. 创建一个react-native.config.js在主应用程序文件夹中命名的文件,其中包含App.jsindex.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. 从现在开始,您可以从android/app/src/main/assetsreact-native 应用程序内部访问所有文件例如:
<Image
   style={styles.ImageStyle}
   source={{ uri: 'asset:/YOUR_FOLDER_NAME/img' + Math.floor(Math.random() * 100) + '.png' }}
/>