React中如何动态导入图片?

15

在网上看到了一些答案,但是没有清晰的解释,而且这些解决方案也行不通。所以我现在要做的是:

  • 我有一个包含很多图片(数千张)的文件夹——目前保存在src/assets/images文件夹下
  • 给定一组图片作为输入,我想要动态地渲染这些图片,而不是导入全部图片,因为数量太大了,根本不可能

这是我当前的实现方式(无法正常工作):

// for example
const imageList = ['img1', 'img2', 'img3' /*...so on */]

const getImagePath = (image) => {
  return `../assets/images/${image}.jpg`
}

function ImagesPage() {
  return (
    <>
      <p>Below should show a list of images</p>
      {imageList.map((img) => {
        return <img src={require(getImagePath(img))} />
      })}
    </>
  )
}

根据我在网上阅读到的信息,这与 webpack 的工作方式有关,只有在require中输入完整的字符串路径才能正常工作:

// This works:
<img src={require('../assets/images/img1.jpg')} />

// But all these will not work:
<img src={require(getImagePath(img))} />

const img = 'img1.jpg'
<img src={require(`../assets/images/${img}`)} />

你知道我如何使得这个动态导入图像在我上面描述的场景中工作吗?我认为这篇文章对于其他正在寻找答案的人也会很有帮助。


@Daryil 把你的图像文件夹移动到公共文件夹是一个选项吗? - kiranvj
4个回答

25

加上 .default 就可以解决问题

<img src={require(`../../folder-path/${dynamic-filename}.png`).default} />

2022年11月更新

升级到Webpack 5后,您将不再需要添加.default。事实上,相反,如果您保留它,由于没有src属性添加到图像中,将不会显示任何图像。

<img src={require(`../../folder-path/${dynamic-filename}.png`)} />

这是我采用的方法,谢谢。 - alextrastero

5

简而言之;

// All of these works

const fileNameExt = 'foo.jpg'
<img src={require('../images/' + fileNameExt)} />
<img src={require(`../images/${fileNameExt}`)} />

const fileName = 'foo'
<img src={require('../images/' + fileName + '.jpg')} />
<img src={require(`../images/${fileName}.jpg`)} />

// These does not work:

const myPathVariable1 = '../images/' + 'foo' + '.jpg'
<img src={require(myPathVariable1)} />

const myPathVariable2 = '../images/' + 'foo.jpg'
<img src={require(myPathVariable2)} />

您可以使用表达式动态 进行 require

文件名:

const imageList = ["img1", "img2", "img3", ... ]

渲染 UI 需要在 require 中添加目录 路径扩展名

{
  imageList.map(img => {
    return <img src={require("../assets/images/" + img + ".jpg")} />
  })
}

为什么它能够工作?

Webpack可以理解这个表达式,通过生成有关目录和扩展名的上下文信息,并可以加载所有匹配的模块。


1
谢谢。为了让其他人在以后阅读时也受益: 所以这个表达式不起作用 <img src={require("../assets/images/${img}.jpg")} />,但是这个 <img src={require("../assets/images/" + img + ".jpg")} /> 起作用? - Daryll
1
@Daryll 是的,正如我在这里详细解释的那样 - https://stackoverflow.com/a/62095265/2873538,为了使动态 require 起作用,简单来说,我们需要提供一个表达式,Webpack 可以根据目录(最好还包括文件扩展名)来分析和理解。在这个答案中添加了 TLDR。 - Ajeet Shah

2
  // for example
const imageList = ['img1', 'img2', 'img3' /*...so on */]

const getImagePath = (image) => {
  return `../assets/images/${image}.jpg`
}

function ImagesPage() {
  return (
    <>
      <p>Below should show a list of images</p>
      {imageList.map((img) => {
        return <img src={require(getImagePath(img)).default} />
      })}
    </>
  )
}

如果您正在使用 "create react app",在 require 后添加 .default 即可正常工作,它可以从本地图像文件夹动态设置所有图像。

2

将您的getImagePath函数更新为返回一个img元素。

const getImage = (image) => {
   return <img src={require(`../assets/images/${image}.jpg`)} />
}

那么你的map函数将会是这样的:
imageList.map((img) => {
   return getImage(img);
});

1
谢谢,伙计!救了我的一天。我花了将近1个小时来处理这个元素。 - Naga Hemanth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接