React Images Won't Load when I pass my src value through array - reactjs

So when I use src={require('images/img-1')} my image loads fine
However, I'm trying to pass in the src through a data component, so the code would look like this
export const CardData = [
{
src: '../images/img-2.jpg',
text: 'Travel',
},
Then I map through my code and would use
{CardData.map((item, index) => {
<img
src={item.src} />
But this doesn't work because I can't add require in it. How would I write the same code but include require?
I tried src={require{item.src}} but it didn't work for me

First of all you should map your array like this
{ CardData.map((item, index) =>
<img
src={item.src}
/>
}
Then you don't need to require the image in the tag and you just need to import it at the top
like this
import MyImg from '../images/img-2.jpg';
// use MyImg allias for using that image
export const CardData = [
{
src: MyImg,
text: 'Travel',
},

Related

I am trying to dynamically create a Mui icon using React.createElement. However, React lowercases the element. Is there a way to keep case?

I am getting service.icon from JSON, so it looks like so
[
{
"icon": "AdminPanelSettingsIcon",
}
]
I am using React.createElement() like so,
data.map((service) => {
let icon = React.createElement(
service.icon,
{ key: service.icon },
null);
});
my output is <adminpanelsettingsicon></adminpanelsettingsicon>
is there anyway to keep case, or convert to PascalCase so it renders like so <AdminPanelSettingsIcon></AdminPanelSettingsIcon>
Note: Is there anyway to dynamically display mui icons based on specified JSON aka api call.
The docs specify:
React.createElement(
type,
[props],
[...children]
)
The type argument can be either a tag name string (such as 'div' or
'span'), a React component type (a class or a function), or a React
fragment type.
You're attempting to create an element using the string "AdminPanelSettingsIcon". Instead you should be attempting this by passing in the class:
React.createElement(AdminPanelSettingsIcon)
You can do this by converting your list to use classes as the value:
[
{
// The value is a class now, not a string
"icon": AdminPanelSettingsIcon,
}
]
Update:
If you are using https://www.npmjs.com/package/#material-ui/icons (or any other library), you can dynamically import all of the components like this:
//Preparing, it should run inside async function
let maps = {}
let listIcon = [];
await import('#material-ui/icons').then(res => {
listIcon = res
})
for(let icon of listIcon){
maps[icon.constructor.name.toLowerCase()] = icon;
}
//Render
data.map((service) => {
const component = maps[service.icon] || DefaultComponent;
let icon = React.createElement(
component,
{ key: component },
null);
});
Original answer:
If the API output is predictable (service.icon is just a component of the components you defined)
You can do this:
//Import...
//Defined maps
const maps = {
"adminpanelsettingsicon": AdminPanelSettingsIcon,
"adminpanelsettingsicon2": AdminPanelSettingsIcon2,
"adminpanelsettingsicon3": AdminPanelSettingsIcon3,
}
//Render
data.map((service) => {
const component = maps[service.icon] || DefaultComponent;
let icon = React.createElement(
component,
{ key: component },
null);
});
It'll work as you wish
Simple way to do this,
In your .jsx file :
import Icon from '#mui/material/Icon';
export default function MyComponent() {
const iconName = `home`
return (<Icon>{iconName}</Icon>);
}
As a prerequisite, you must include this line in yout index.html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
VoilĂ  !
Sources :
Mui DOC

How can i add custom marker to map using react-map-gl?

i want to add custom marker to my map. Im using react-map-gl library and components Layer and Source. My code is:
import pin from "../images/pin.svg";
. . . .
const geojson: GeoJSON.Feature<GeoJSON.Geometry> = {
type: 'Feature' ,
geometry:{
type: 'Point' as 'Point',
coordinates:[21.300465619950796 , 48.70795452044564],
},
properties: {
name: "Marker",
}
};
const layerStyle = {
id: 'point',
type: 'symbol' as 'symbol',
source: 'Marker',
layout: {
'icon-image': 'pin',
'icon-size': 1
},
paint: {
'icon-color': '#78546'
},
};
.
.
.
.
<Source id="my-data" type="geojson" data={geojson}>
<Layer {...layerStyle} />
</Source>
But my icon doesnt appear. Can you help me please?
Basically mapbox needs to have a reference of the image already stored before it can assigned it to a pin/marker in a layer symbol.
Here is what I did, and hope it helps you
First create a onLoad function that will be called when the map loads
<Map
...
ref={mapRef} // need a ref to reference it later if you don't have it already
onLoad={onLoad}
/>
In the onLoad function create a new image and load its content
const onLoad = (e) => {
if (mapRef.current) {
const pinImage = new Image();
pinImage.onload = () => {
if (!mapRef.current.hasImage('pin')) {
mapRef.current.addImage('pin', pinImage, { sdf: true });
}
}
pinImage.src = pin; // pin is your svg import
}
}
It should now work with your current layer attributes, please note that the name given in the addImage call (the first argument 'pin') must match the image-icon in the layer settings.
Note: Also make sure the layer style source attribute matches that of its source id.
Something like this:
import ReactMapGL, {Marker} from 'react-map-gl';
<ReactMapGL width="100vw" height="100vh">
<Marker longitude={longitude} latitude={latitude} >
<img src={pin} />
</Marker>
</ReactMapGL>

How to use display slideshow items correctly in React?

This slideshow is rendering an array of items instead of individual items. I think I need to split up the array in order to get it right. see my link here: https://codesandbox.io/s/exciting-waterfall-gqekv?file=/slideshow2.js . My log shows that mapped items is an array, does that mean i need to use splice or spread somehow?
I need each slide to say one name, not the whole array on one slide. If I remove the DUMMY COMPONENT it works fine for some reason?
import React from "react";
import AliceCarousel from "react-alice-carousel";
import "react-alice-carousel/lib/alice-carousel.css";
const items = [{ name: "Bob" }, { name: "jill" }, { name: "wesker" }];
let mappeditems = items.map((item, index) => <div key={index}>{item}</div>);
console.log(mappeditems);
console.log(Array.isArray(mappeditems));
const Gallery = () => {
return (
<div>
<AliceCarousel mouseTracking items={items}>
{mappeditems}
<div>DUMMYCOMPONENT</div>
</AliceCarousel>
</div>
);
};
export default Gallery;

React img src from object

How to exract image source from object for img src ?
I have constant defined like this:
const DUMMY_DATA = [
{
name: "Frozen",
image: "../../assets/categories/Frozen.png",
categories: [],
},
{
name: "Baby Care",
image: "../../assets/categories/BabyCare.png",
categories: [],
},
{
name: "Bakery",
image: "../../assets/categories/Bakery.png",
categories: [],
},
]
I want to map over the array and render a list of each object like the below:
const categories = DUMMY_DATA.map((item) => {
return (
<li key={item.name} className={classes.category}>
<img src={item.image} alt="category" />
<span>{item.name}</span>
</li>
);
});
return (
<nav>
<ul className={classes.navBox}>{categories}</ul>
</nav>
);
unfortunately it doesn't work
I would suggest importing the images instead of using paths.
import image1 from '../path/image-1.png'
import image2 from '../path/image-2.png'
import image3 from '../path/image-3.png'
const DUMMY_DATA = [
{
...
image: image1,
},
{
...
image: image2,
},
{
...
image: image2,
}
]
The reason for this is that when your React application is compiled, the relative paths to access those images will be different.
If you really want to use paths instead of importing, I'd suggest using absolute paths but it's not recommended.
I tried to replicate your code in CodeSandBox and it seems everything is syntactically correct. Problem seems to exist in the image paths within your dummy data.

React Component with JSON Image path

I have a react component that is pulling in some data from a local json file. That data has some links to images. However the images aren't loading even though the paths are correct. I was using require before but in a different code setup. Now that I've transitioned it to this the images won't load. i'm using webpack 4 so i'm guessing i need to require the images again? How do i do that in the below statement ?
the part that is failing is the 'image={release.imageURL}' which is being passed to the 'src' of the component
import React from "react";
import ReactDOM from "react-dom";
import Release from "./release.js"
import data from "../data/releases.json"
const allReleases = data.map(release => {
return (
<div className="column-2">
<Release
key={release.id}
url={release.releaseURL}
image={release.imageURL}
cta={release.cta}
title={release.title}
artists={release.artists}
/>
</div>
)
})
const Releases = () => {
return (
<div>
<div className="row">
<h3>All Releases</h3>
{allReleases}
</div>
</div>
)
}
export default Releases;
Without knowing the details of what you're trying to achieve, I think you can do the following:
Because you're providing paths in your json, you'll need to require them dynamically.
releases.json
[
{
imageURL: "/image01.jpg"
},
{
imageURL: "/image02.jpg"
},
{
imageURL: "/image03.jpg"
}
]
then assuming you know the relative path to these images you can require them inside your map
const allReleases = data.map(release => {
return (
<div className="column-2">
<Release
url={require('./path/to/images' + release.imageURL)}
/>
</div>
)
})
Alternatively, you could make your releases.json a js file and import your images there and put them in your data as variables.
Bro, I was working on this problem and eventually figure it out:
1- All you have to do is changing the path of the image from your JSON file. That means the path should be related to your react component (allReleases).
2- Next thing, instead of using
*
<Release
key={release.id}
url={release.releaseURL}
image={release.imageURL} // ==> WRONG
cta={release.cta}
title={release.title}
artists={release.artists}
/>
Just go with:
*
<Release
key={release.id}
url={release.releaseURL}
image={`${release.imageURL}`} // ===> CORRECT
cta={release.cta}
title={release.title}
artists={release.artists}
/>

Resources