在 React 中动态渲染图像非常困难

Posted

技术标签:

【中文标题】在 React 中动态渲染图像非常困难【英文标题】:Rendering image dynamically is so hard in React 【发布时间】:2019-10-29 02:00:02 【问题描述】:

在尝试了几个小时的各种方法并检查了每个相关链接之后,我找不到任何合适的方法在 React 中动态呈现图像。

这就是我想要做的。

我有一个对象数组,其中每个对象都有一个名为 name 的属性。我正在使用 map 函数 map 循环遍历这个数组并返回 img 元素的数组,如下所示。

<img className="img-thumbnail" src=require('../../public/images/'+item.name+'.png')/>

其中 item.name 是我要显示的图像文件的名称,为此 require 给我错误“找不到模块”。 此外,我需要实现一些后备选项,而不是显示损坏的图像以防图像文件不存在,我想显示默认图像

这是我尝试过的事情:

在 require 上使用 try 和 catch 块并从 img 元素调用此函数

setImage(data)
try
    return require( '../../public/images/'+data+'.png' ) //actual image
catch(err)
    console.log(err);
    return require('../../public/images/fallback.png'); //fallback
           

<img className="img-thumbnail" src=this.setImage(item)/>

使用导入,在上述同一个函数内,出现错误 import cannot be called from inside of function

使用 react-image 库。原来它不支持本地图像。

有什么帮助吗?

【问题讨论】:

src="/images/fallback.png" 呢?这更像是一个 webpack 或您正在使用的任何捆绑器的问题,而不是一个 react js 问题恕我直言。 这些图像是否在应用程序中可用(静态和捆绑的一部分)或者这些 uri 是从服务器动态获取的? @johnnypeter 图片在应用程序内,但我从数据库中获取对象。组件挂载后出现问题,因为在那之后 require 似乎不起作用,并且在目录中仍然存在图像时显示找不到模块 @happysharma 如果您的网址在编译时已知,我添加了一个可以帮助您的答案 您正在静态渲染“动态”图像。如果您的图像是公开的,那么只需通过带有相应 JSX/html 元素的 URL 来获取它们,如果您的图像不是公开的,那么您将不得不异步获取 base64 数据(和 mime 类型),这可以通过“redux”之类的东西来完成-saga”(尽管对于您想要实现的目标而言,这似乎过于复杂)。 【参考方案1】:

以上所有答案都很有帮助,但不幸的是,没有一种方法对我有用。所以再次深入挖掘,我发现 require 给出了错误“找不到模块”,因为在 webpack 捆绑我的代码之后,require 丢失了上下文。这意味着给定的相对路径不再有效。

我需要做的是保留我使用 require.context 所做的上下文;

这是最终的有效代码。

//getting the context of image folder
  const imageFolderContext = require.context('realtive/path/to/image/folder')

 //function to check if image exist
   checkFile(data)
       try
            let pathToImage = './path/to/image/relative/to/image/folder/context
            imageFolderContext(pathToImage)  //will check if Image exist
            return true                      //return true if exist
       catch(err)return false
  

//rendering image element dynamically based on item name and if exist or not
<img src=this.checkFile(itemName)?imageFolderContext('path/to/image/relative/to/context'):imageFolderContext('default/image/path/) />

别忘了绑定checkFile函数

【讨论】:

【参考方案2】:

在编译期间静态检查需求。 requires 的路径不能是动态的。由于您的捆绑包中有静态图像并且对象映射到其中之一,因此您可以按照以下方式解决问题

const images = 
  image1: require('local/path/to/image1'),
  image2: require('local/path/to/image2'),
  image3: require('local/path/to/image3'),


const defaultImage = require('local/path/to/defaultImage');

const Img = ( name ) => 
  // here name is the name for the image you get from api.. 
  // This should match with the keys listed the iages object
  return <img src=images[name] ? images[name] : defaultImage/>

【讨论】:

它适用于静态图像,但不适用于只有在获取对象后才能形成路径。 @happysharma 因为你所有的图片都是静态的,捆绑在你的应用程序中,你可以通过上述方法将名称映射到路径。【参考方案3】:

这里有一个棘手的方法来处理这个问题。使用 react state 检查是否有错误。

如果为真,则显示回退,否则,显示实际图像。

setImage = (data) => 
  const image = new Image();
  image.src = '../../public/images/'+data+'.png';
  this.setState(
    hasError: false
  )
  image.onerror = () => 
    this.setState(
      hasError: true
    )
  
  return image.src;

// into render
this.state.hasError
? <img src="../../public/images/fallback.png" />
: <img className="img-thumbnail" src=this.setImage(item)/>

更新:示例

var image = new Image();
image.src = 'fake.jpg';

image.onerror = () => 
  console.log('image doesn t exist');

【讨论】:

你如何检查图像是否存在?因为我无法在组件安装后使用 require 获取图像,尽管图像仍然存在于目录中 如果图片不存在会进入onerror。 函数显示图像存在,但再次需要时显示找不到模块 你不再需要使用 require() 了。 没有它,图像将无法加载。网址不能这样反应,你要么在顶部导入它,要么在 src 中要求。【参考方案4】:

我不知道你为什么需要它可以像这样简单地完成。你可以导入这样的东西。像这样导入图片

import fallback from '../../public/images/fallback.png';

对于动态图像,我建议制作一些键值对。例如:

让数据 = 图片1:../../public/images/image1.png, 图片2:../../public/images/image1.png 并正常导入

渲染中的一些东西

可能是这样的。

render()
  return(
   <img className="img-thumbnail" src=img?img[type]:fallback/> //something its just refrence(where type is something which you want dynamically add image)
)

【讨论】:

src 不会立即采取路径。您使用 require 或 first import。我的前一个案例,但一旦组件安装我就无法做到这一点

以上是关于在 React 中动态渲染图像非常困难的主要内容,如果未能解决你的问题,请参考以下文章

渲染大量图像 React Native

在 React 中渲染动态输入字段

在 React 中的图像标签中渲染 css 类

如何在 React 中动态导入图像?

React基础-JSX语法列表渲染详解

动态渲染 React 组件