【问题标题】:Loading images using require in react app在 React 应用程序中使用 require 加载图像
【发布时间】:2020-08-18 20:17:08
【问题描述】:

我是 React 新手,我正在尝试创建一个涉及卡片的游戏,其中 websocket 返回一组卡片名称,并在前端从本地图像目录生成正确的卡片图像。从 websocket 返回的卡片名称与图像的文件名匹配,例如“map”对应于图像“map.jpg”。我正在尝试映射数组并为数组中的每个卡名创建一个图像标签。我读到最好的方法是使用require(),所以我尝试做类似的事情

//inside component
let cardImgs;
...
socket.on(RECEIVED_STARTING_HAND, (hand) => {
     cardImgs = hand.map(cardName => <img src= {require(`../../card_images/${cardName}.jpg`)}/>
})

...所以稍后在我的组件中我可以做这样的事情:

return (
 <div>
     <h1>My hand</h1>
        {cardImgs}
 </div>
  ...
)

但是,cardImgs 不会呈现。在我的组件的return 声明中,我测试了直接渲染图像并且它可以工作,例如

const map = "map"
return (
 <div>
     <h1>My hand</h1>
        {cardImgs}
 </div>
  ...
//this one renders!!!
<img src={require(`../../card_images/${map}.jpg`)} /> 
)

我使用 Create-React-App 创建了我的 react 应用程序,我读了一些内容说我应该重新配置我的 webpack.config.js 文件,但是我也读了一些内容说我不应该碰它,除非我需要。我不确定为什么require() 在我的组件的return 语句中起作用,但在给定图像标签数组时它不起作用。我是否遗漏了什么,或者您对在 React 中动态加载图像的更好方法有什么建议?谢谢!

【问题讨论】:

  • 使用肯定会有帮助的导入。
  • 我有大约 40 张图片,我想根据给定的卡片动态加载图片。拥有 40 个导入语句只会变得混乱。我希望有一个替代方案。
  • require 在反应中不起作用,我能想到的唯一其他方法是将图像托管在 AWS 或 Azure 等云中,然后您可以动态加载它。
  • 有:将您的静态资产作为静态资产托管,而不是尝试将它们捆绑在一起。尤其是如果数据不会每半天更改一次,例如图片或网站 CSS 或 webfonts。然后使用&lt;img&gt; 组件加载它们,因为这就是img 元素的用途。
  • @Mike 'Pomax' Kamermans 你能举个例子吗?您的意思是将它们作为静态资产托管在云中吗?

标签: javascript reactjs create-react-app


【解决方案1】:

我建议在渲染中简单地处理状态项hand。当您更新该值时,将触发渲染并创建您的图像。

{hand.map((cardName, index) => (
      <img key={cardName} src={`pathtoserver/card_images/${cardName}.jpg`}/>
     ))}

Demo

【讨论】:

  • 如果你使用create-react-app,你是否知道服务器的路径是什么?我正在尝试从不同的文件夹开始导航,但找不到正确的路径。
  • 在创建反应应用程序时,您将无法访问服务器,因为它只是用于开发的精简服务器设置,如果您的后端服务器由您决定。
  • react 没有对给定服务器的默认访问权限。如果对您有帮助,create-react-app 中的静态资产将保存在 /public 中。如果您的所有卡片图像都保存在 react 应用程序中而不是服务器中,这可以为您提供帮助
  • @Mike'Pomax'Kamermans 好点,假设在上面的示例中没有任何内容,但会更新它
  • 很好,评论已撤回。人们认为他们可以为 key 属性经常使用数组位置,这就是 React 应用程序运行不佳的主要原因之一。
【解决方案2】:

如果你想从本地文件夹渲染图像,你可以使用导入语法导入你需要的图像,然后在你的 img 标签中使用它

import card1 from '../you/path/to/image.png';
import card2 from '../you/path/to/image.png';
import card3 from '../you/path/to/image.png';

const cards = {
    nameToCard1: card1,
    nameToCard2: card2,
    nameToCard3: card3,
}

在您的套接字方法中:

socket.on(RECEIVED_STARTING_HAND, (hand) => {
cardImgs = hand.map(cardName => cards[cardName] />

})

在你的渲染方法中:

return (
<div>
    <h1>My hand</h1>
    <ul>
        {cardImgs.map((img) => <li><img key={img} src={img} /></li>)}
    </ul>
</div>

)

希望对你有帮助,祝你有美好的一天。

【讨论】:

  • 记得在使用map 时添加key 属性(并记住它们应该是组件的真实唯一值,而不是“数组位置”)
  • 哦,你是对的。我将继续编辑帖子以获得正确的示例
  • 然后你做了我提醒你不要做的事情。使用唯一的标识符,即始终标识该元素:如果我有['a','b']['b','a'],我是更改了这两个元素,还是只是交换了它们?这就是key 的用途。你已经有了完美的唯一标识符,它就在那里,你已经将它分配给src将它用作DOM diffing key。请阅读reactjs.org/docs/lists-and-keys.html#keys 并理解为什么需要给这个属性一个合适的值,因为使用列表位置是在自取其辱。
  • 感谢您提供的信息,很抱歉,我更正了使用图像的 src 作为唯一标识符的问题
  • 但是为什么key={`${img}`}?就说key={img}?而且您正在使用箭头函数,所以:&lt;div&gt;&lt;h1&gt;..&lt;/h1&gt;&lt;ul&gt;{cardImgs.map(url =&gt; &lt;li&gt;&lt;img key={url} src={url} /&gt;&lt;/li&gt;)}&lt;/ul&gt;&lt;/div&gt; 完成了吗?
猜你喜欢
  • 2021-09-01
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多