【问题标题】:Rendering image dynamically is so hard in React在 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”(尽管对于您想要实现的目标而言,这似乎过于复杂)。

标签: javascript reactjs


【解决方案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。我的前一个案例,但一旦组件安装我就无法做到这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多