How to dynamically render images in react? - reactjs

How to dynamically render/ import images in react / typescript?
I'm using Typescript with React.
Following is what I want to achieve.
but this is not working. It is not resolving the expression { 'assets/icons/' + media + '.svg'} .
<div className="medias">
MEDIAS.map((media) =>
(<img src={ 'assets/icons/' + media + '.svg'} />)
)
</div>
This is what I've tried.
const Medias = async () => {
return (
<div className="medias">
{await Promise.all(
MEDIAS.map((media) =>
import(`assets/icons/${media}.svg`).then((v) => v.default)()
).map((item) => <img src={media} />)
)}
</div>
);
};
export default Medias
I want to dynamically import and render images based on the above logic.
In angular or vue this can be achieved easily inside templates. But here in react it seems like not working.
But seems like it is not working.
Is there a work around?

For local image files instead of importing every image while mapping over them, you can make a separate file and add all the imports in that file and make an object of all the images, and export that object to use anywhere dynamically. I have created an example on the sandbox here you can check this out for your case.
import img1 from "./assets/1.jpeg";
import img2 from "./assets/2.jpeg";
import img3 from "./assets/3.jpeg";
export const imagesPath = {
img1: img1,
img2: img2,
img3: img3
};
Now, this can be used to dynamically use the images as shown in the code snippet below.
Medias.map((media) => (
<img
src={imagesPath[media]}
alt="Dynamic Image"
key={media}
/>
))
To see the working example checkout the code sandbox link given above.

Related

Background image is not displaying using either the style attribute or a Tailwind utility class

I am using Tailwind CSS to build a landing page that I have divided into sections. I want to use a background image on the particular <div> so that it only shows up in that section. I also plan to put a button and text box on top of it.
My attempt is just not working. I tried using url() in both a Tailwind bg class and a normal React style prop, but neither version works.
Using the React style prop:
import React from 'react'
import image from '../../public/images/Rectangle 37.png'
const ReadySection = () => {
return (
<div
className="border-solid border-2 border-sky-500 h-[300px]"
style={{backgroundImage: `url(${image})`}}
>
</div>
)
}
export default ReadySection
Using the Tailwind utility class:
import React from 'react'
const ReadySection = () => {
return (
<div className="bg-[url('frontend\public\images\Rectangle 37.png') border-solid border-2 border-sky-500 h-[300px]">
</div>
)
}
export default ReadySection
I'm using create-react-app and named the app "frontend", so the path of the image is:
frontend/public/images/Rectangle 37.png
The path of my ReadySection component is:
frontend/src/components/ReadySection.js

Why local svg icons not resolve in react.js projects?

I have local icons, and I add icons in build folder like screenshot below, then I was import icons like that import {ReactComponent as MyIcon} from "build/icons/my-icon.svg";, but still say "Can't resolve 'build/icons/my-icon.svg'", any idea?
Screenshot:
you need to use file-loader
and when you import dont use brackets since its default export just chose the name directly
import myIcon from "build/icons/my-icon.svg";
const App = () => {
return (
<div className="App">
<img src={myIcon} />
</div>
);
}
Svg tag
second option would be to extract the svg tag and put it directly into you component ,
const App = () => {
return (
<div className="App">
<svg .... // copy the content of your .svg
</svg>
</div>
);
}

Rendering Array of Images in React [duplicate]

This question already has answers here:
Loop inside React JSX
(84 answers)
Closed 2 years ago.
I need help. I have been searching similar posts, but none of them solved my problem (imagesPool.js)
import React from 'react';
const imagesPool = [
{ src: './images/starbucks.png'},
{ src: './images/apple.png'},
{ src: './images/mac.png'}
];
export default imagesPool;
Rendering the images (App.js) :
import React from "react";
import imagesPool from './imagesPool';
const App = () => {
return (
<div>
<img src={imagesPool} />
</div>
)};
export default App;
Result : No images being displayed
You should loop through your images because src expects a string location to the image.
import imagesPool from './imagesPool';
const App = () => {
return (
<div>
{imagesPool.map((imgSrc, index) => (<img src={imgSrc.src} key={index} alt="Make sure to include a alt tag, because react might throw an error at build"/>))}
</div>
)};
In react you solve things like conditionals, iterating, etc. with javascript (Remember, <img> is also just javascript and gets parsed into React.createElement("img")).
Since img expects a string in the src-property, we need to iterate over the array of sources and produce an img-Element for every source:
<div>
{
imagesPool.map(({ src }) => (<img key={src} src={src} />))
}
</div>
With key you tell react how to recognize that an element is the same with subsequent renderings.
You always need to import React from 'react' if you are rendering jsx/tsx. In your code, you are returning jsx, thus you need to import react.
import React from 'react';
import imagesPool from './imagesPool';
const App = () => {
return (
<div>
{imagesPool.map((image) => <img key={image.src} src={image.src} />)}
</div>
)};
export default App;

How to transform anchor links from WP API into Next.js <Links> using `dangerouslySetInnerHTML`

I'm using a headless approach for a React (Next.js) + Wordpress API app.
The problem I'm running into is when the content editor adds an anchor tag into WP's WYSIWYG editor. I'm parsing that content using React's dangerouslySetInnerHTML and therefore a plain <a href="whatever"> is generated.
How do I go about transforming that into a next.js <Link> tag?
Not sure if this helps, but this is a piece of my code:
<React.Fragment>
<h1>Page: {title.rendered}</h1>
<div
className="richtext"
dangerouslySetInnerHTML={{ __html: content.rendered }}
></div>
{wpData.acf.modules.map((mod, index) => (
<React.Fragment key={`module=${index}`}>
{renderComponents(mod)}
</React.Fragment>
))}
</React.Fragment>
Since I'm using a decoupled solution, the anchor tag points to the server url, which leads to a broken page.
Ok, so the solution I found was posted here: https://stackoverflow.com/a/51570332/11983936
Basically factored the content display into its own helper function and used that in the components I need:
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { useRouter } from 'next/router';
import fixLink from './fixLink';
const useRenderRichtext = props => {
const router = useRouter();
const handleAnchorClick = e => {
const targetLink = e.target.closest('a');
if (!targetLink) return;
e.preventDefault();
const redirectThis = fixLink(targetLink.href);
router.push(`/${redirectThis}`);
};
return (
<Fragment>
<div
onClick={handleAnchorClick}
onKeyPress={handleAnchorClick}
className="richtext"
dangerouslySetInnerHTML={{ __html: props }}
></div>
</Fragment>
);
};
export default useRenderRichtext;

Displaying images with webpack using require.context

I have made my first React app using Webpack with the create-react-app tool.
I have an unknown amount of images in a folder I would like to display as my apps background at random. Using some code from the Webpack docs and other threads I use this code in my component.
import React, { Component } from 'react';
import './styles/css/App.css';
function requireAll(r) {
r.keys().forEach(r);
var images = r.keys();
images = images.map( path => "./images/backgrounds/" + path );
console.log(images);
return images;
}
var images = requireAll(require.context('./images/backgrounds/', true, /\.jpg$/));
let randomIndex = Math.floor(Math.random() * images.length) + 0;
var randomImgRef = images[randomIndex];
class App extends Component {
render() {
return (
<div className="App" style={{backgroundImage: "url(" + randomImgRef + ")"}} >
<h1>hi</h1>
</div>
);
}
}
export default App;
This seems to work, the background style has the right path and my console logs the right path also. But no images are displayed, and I'm clueless.
I think Webpack might not be including the images in the build, though the code I'm using seems like it should do that. So I'm clueless.
Any ideas?
I think for your example you just have to use randomImgRef.default so use the default property to get the url.
EXAMPLE Using require.context to display images:
const photos = importAll(require.context('../../assets/photos', false, /\.(png|jpe?g|svg)$/));
Render:
<div>
{photos.map((photo, i) => (
<div className="photo" key={i}>
<img src={photo.default} alt=`photo-${i}` />
</div>
))}
</div>

Resources