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

时间:2019-06-14 12:16:52

标签: javascript reactjs

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

这就是我想要做的。

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

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

其中item.name是我要显示的图像文件的名称,对此它的要求是给我错误“找不到模块”。 而且我需要实现一些后备选项,在不存在图像文件的情况下显示损坏的图像,而我想显示默认图像

这是我尝试过的事情:

  • 使用try和catch阻止require并从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)}/>

  • 使用导入功能,与上述功能相同,无法从功能内部调用错误导入

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

有什么帮助吗?

4 个答案:

答案 0 :(得分:1)

这是一种处理问题的棘手方法。使用react state检查是否存在错误。

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

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');
}

答案 1 :(得分:0)

我不知道您为什么需要它可以像这样简单地完成。您可以导入类似这样的内容。像这样导入图像

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

对于动态图像,我建议要么做一些键值对。例如:

让数据= {     图片1:../../public/images/image1.png,     image2:../../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)
)
}

答案 2 :(得分:0)

在编译期间对需求进行静态检查。 require的路径不能是动态的。由于您的套装中有静态图片,并且该对象映射到其中一个静态图片,因此您可以按照以下解决方案进行操作

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}/>
}

答案 3 :(得分:0)

以上所有答案都很有帮助,但毫无疑问,这两种方法都不适合我。因此,再深入一点,我发现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函数