Reputation: 81
i have objects with keys img and the value is relative path to image folder placed in src folder '/images'. I'm using map to loop over destructured data and adding it to DOM with simple template like this:
<div key={id}>
<img src={img + '.jpg'} alt='{title}' />
</div>
And my data object looks like this:
const category = [
{
id: 1,
title: 'cizme',
img: './images/cizme',
link: './cizme'},
...
data(category) is defined in App component
import data from './data';
import Home from './Home';
import logo from './images/logo_fin-01.png';
import Navbar from './Navbar';
function App() {
return (
<div className='App'>
<Navbar logo={logo} />
<Home data={data} />
</div>
);
}
export default App;
and Home comp is:
const Home = ({ data }) => {
return (
<div className='kat'>
{data.map(({ id, title, img, link }) => (
<li key={id}>
<span>{title}</span>
<div className='img-container'>
<img src={img + '.jpg'} alt={title}></img>
</div>
</li>
))}
</div>
);
};
export default Home;
Now, and in browser paths are displayed correctly, with no errors, but it says image 'could not load the image'.I tried to copy images folder to public but then i get error 'its out of scope or sth like this(i forgot)'.So what should i do?
update: require() works in sandbox, localy doesn't.
https://codesandbox.io/embed/zealous-christian-0j3v3?fontsize=14&hidenavigation=1&theme=dark
Upvotes: 1
Views: 6619
Reputation: 413
Your current approach won't work (unless you have to import the images over a loop), since you've kept these images in src
folder. By keeping the image url as relative to the current folder won't work, because when passing a URL to src (and not an imported image), your browser starts rendering, the img
's src
attribute will look with respect to the URL, and not the folder from which the javascript file is being loaded and executed.
In other words, if my component serving this mapped image route is at the URL xyz.com/something/currentScreen
, then './images/cizme' + '.jpg'
will translate to xyz.com/something/images/cizme.jpg
, which doesn't exist.
Since you are trying to dynamically render these images, a good way would be to place them in public
folder, (and then inside 'images' folder, since your URL says so), and then have '/images/cizme' + '.jpg'
which will result in xyz.com/images/cizme.jpg
loading properly, because they exist inside the public
folder.
Edit: Can you confirm that your browser paths are correct? Try opening Network Tab as prescribed in the comments.
Upvotes: 1
Reputation: 203408
I'm assuming that since your category
array is specifying local/relative paths that it's generated at compile time (and not some dynamic value at run-time), and as such, will have access to assets located in the src
source directory.
You can either import all the images and specify them in the category
array.
import img1 from './images/cizme.jpg';
...
const category = [
{
id: 1,
title: 'cizme',
img: img1,
link: './cizme'
},
...
Or since listing all the imports explicitly is impractical, you can just require them in the data.
const category = [
{
id: 1,
title: 'cizme',
img: require('./images/cizme.jpg'),
link: './cizme'
},
...
Then you can just render the images as per normal.
{category.map(({ id, img, title}) => (
<div key={id}>
<img src={img} alt='{title}' />
</div>
))}
I updated my linked codesandbox to reflect your code. If the exported data
uses require
to pull in the images, then Home
can simply attach the img
value to the src
attribute.
const Home = ({ data }) => {
return (
<div className="kat">
{data.map(({ id, title, img, link }) => (
<li key={id}>
<span>{title}</span>
<div className="img-container">
<img src={img} alt={title}></img>
</div>
</li>
))}
</div>
);
};
Example with cat1.jpg, cat2.jpg, and cat3.jpg images located in a "./images" directory in src
.
Code:
data.js
const data = [
{
id: 1,
title: "cizme",
img: require("./images/cat1.jpg"),
link: "./cizme"
},
{
id: 2,
title: "cizme",
img: require("./images/cat2.jpg"),
link: "./cizme"
},
{
id: 3,
title: "cizme",
img: require("./images/cat3.jpg"),
link: "./cizme"
}
];
export default data;
App.js
import data from "./data";
const Home = ({ data }) => {
return (
<div className="kat">
{data.map(({ id, title, img, link }) => (
<li key={id}>
<span>{title}</span>
<div className="img-container">
<img src={img} alt={title}></img>
</div>
</li>
))}
</div>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Edit to see some magic happen!</h2>
<Home data={data} />
</div>
);
}
Upvotes: 0