Can Dynamic and Constantly changing image URL work with Next/image - reactjs

Can Next/Image use empty string variables for the src that'd get set later via an API?
I have an image url that I'd retrieve from an API. so the image src gets set after runtime. By default it's an empty string '' and then using SWR later it gets set to the full image url, eg https://i.imgur.com/Thgw1b.png
However, I get a build time error, Error: Image is missing required "src" property. Make sure you pass "src" in props to the `next/image` component. Received: {} despite having src already set. The same error occurs if src='' as well.
const myComponent = ({imageURL = ''}) => {
// imageURL starts off as '', then the parent updates that value to a proper image url when the API returns a url value.
return (
<>
// TODO: Fix build time error saying no src is set, despite being set to '' initially
<Image src={imageURL} alt='Dynamic Image' layout='responsive'/>
</>
);
}
Can Next/Image src images be set fully dynamically? Where it starts as an empty string then the src url gets populated later?
I've seen some answers suggesting useServerSide Props, but that won't work in my use case as the image url API gives a different image url every X hours (Hence using SWR). So just loading in once doesn't work.
Note that using <img> tags works perfectly. Initially there's no image, then after the image url gets set to the variable, the img tag loads the image in.

Try rendering the Image conditionally like so :
return (
<>
{imageUrl &&
<Image src={imageURL} alt='Dynamic Image' layout='responsive'/>
}
</>
)

Related

React: Using State Variable In Image Src?

So I've exported all of the images in my image folder by using an index.js inside the same folder and writing exports such as export const Image = require("./image.png");. I then imported said images into my React app with import { Image, Image2, Image3 } from from "./imageFolder";
When I use the imported images as src values in my image tags, they work just fine so I know I've properly imported my image. The big issue that I have though is I've been trying to utilize the value of a state variable in the file to dynamically render a different image based on the state. The state variable's values are varied due to its values deriving from a database request that's stored in a state array.
{
Object.keys(this.state.videos).map((video, index) => {
return (
<div key={index}>
<p>Event: {this.state.videos[video].eventName}</p>
<p>P1 Character: {this.state.videos[video].p1Character}</p>
<p>P2 Character: {this.state.videos[video].p2Character}</p>
</div>
);
})
}
Say that in this instance, the value of {this.state.videos[video].p1Character} is equal to "Image" - which corresponds with the name of the image I imported above. So why can't I do <img src={this.state.videos[video].p1Character} />? Is it possible to do what I'm trying to do?
You cannot do it becaue the p1Character is a string and not a live variable.
You could however import the images as
import * as Images from from "./imageFolder";
and then use the p1Character to reference the image in the Images.
<img src={Images[this.state.videos[video].p1Character]} />
Unless I don't understand what you mean, I don't see how it would be possible to have this this.state.videos[video].p1Character equal to Image/Image2/Image3 if you have just save a reference to them as a string because you are literally just going to be writing src="Image/2/3".
The best thing to do would to be store a unique key string for the images on a record and then just have a simple object map in your component like
const myImageMap = {
image1: Image,
image2: Image2,
image3: Image3
}
/////
///// somewhere in your render
/////
<img src={myImageMap[this.state.videos[video].p1Character]} />
They key is that we are mapping to the strings to actual imported images

Add image to the DOM dynamically in react

I have a socket connection that updates a binary data.
By click I would like to update an image src , the images are created blank with empty src and with id , but I did not found how do I doing something like :
$('imageId').src = 'new src' like in Jquery
I have array of images so I cant define per each image this.ref or something
my socket code: // here I want to update the specific image
divSocket.on('data', (data) => {
var bytes = new Uint8Array(data);
this.setState({
imageSrc : someBufferFunction(bytes)
})
});
my render code
{ this.props.list.map((item,i) =>(
<div className="img">
<img id={`cam${i}`} src={`data:image/jpeg;base64,${this.state.imageSrc}`} />
</div>
))}
the problem is that this.state.ImageSrc will update all images and will show socket data (video) in all the images
I can create an image with specific id in loop but how do I update specific image via props/state
You're using an array to display images ... from props ... this.props.list
This list should contain data for each image ... but item argument isn't used in .map rendering.
I need to make a placeholder
Assuming that props.list doesn't contain any data ... used as loop counter ... renders placeholders only ... you need:
an array of src in local state (this.state.sources = [];)
you should render images using key prop:
{ this.props.list.map((item,i) => (
<div className="img" key={`cam${i}`} >
<img id={`cam${i}`} src={this.state.sources[i]} />
</div>
))}
you can use placeholder image for empty 'cells'
<img id={`cam${i}`} src={this.state.sources[i] ? this.state.sources[i] : "url_somePlaceholder.jpg"} />
New image from socket needs to update an array element using index - not common one for all images in this.state.sources - see React: how to update state.item[1] in state using setState? for inspirations.
If assumed earlier props.list contains image sources at start - copy values into state (in componentDidMount, componentDidUpdate or static getDerivedStateFromProps )

reactjs render image dynamically

To be clear:
<img src={require('../styles/myimage.jpg')} />
works fine. But I want to get this path dynamically as a string from api. In my parent component I fetch it and pass to child:
<img src={require(this.props.image)} />
In this case this.props.image is the same as '../styles/myimage.jpg'. But it does not work for me and throw this error "Uncaught (in promise) Error: Cannot find module "."
How can I fix it?
The directory tree is (I am trying to fetch myimage.jpg from image.js)enter image description here:
And webpack config: enter image description here
Do a simple test, move styles path with contains yours jpg files to same path of your component and try this path in props:
props.image = './styles/myimage.jpg'
then
<img src={require(this.props.image)} />
In addition to the comment what you can do is in your render method try this :
if (!this.props.image) return false;

Dynamic loading of locally stored images with react native

Problem with dynamic loading of image resources within a loop/list.
I have all my static local resources required as such:
assets/images.js
const images = {
appLogo: require('./app-logo.png'),
cardOne: require('./cards/card-1.png'),
cardTwo: require('./cards/card-2.png'),
...
cardForty: require(./cards/card-40.png)
}
export default images;
Then in my list screen:
...
import images from '../assets/images';
...
renderListItems(item) {
const image_name = `images.card${item.cardName}`;
console.log(image_name); // images.cardOne, images.cardTwo etc..
return (
<ListItem avatar>
<Thumbnail square size={80} source={image_name} /> // This is nativebase component which wraps the RN image component
<Body>
<Text>{item.name}</Text>
</Body>
<Right>
<NBIcon name="arrow-forward" />
</Right>
</ListItem>
);
}
...
No resources get loaded. Yet if I change the source={image_name} to source={images.cardOne} directly (where images.cardOne is the exact same as image_name variable on the first iteration) it works - except for the fact that they all have the same image.
I also tried using {{ uri: image_name }} syntax but nothing happens there too.
There doesn't seem to be any solution to this, other than creating a massive switch statement
Well that's because image_name is a string with the value of images.cardOne whereas images.cardOne is also a string but with the value of the actual path of the images in your file system (e.g ./app-logo.png). So if you want to load images object dynamically to image_name, you should use the bracket notation like so:
const image_name = images[`card${item.cardName}`];
That way image_name will now point to the path of your images (e.g ./app-logo.png).

React.js Cant replace image source when image throws a 500 error

I have a React component which basically grabs an image and outputs it. However my issue is that I cant replace the image source when the image throws a 500. My page will return the image path (/images/icons/image.png) however that image itself does not exist, so it throws a 500 on me. This is fine, the issue is it wont trigger the onerror in the image so I cant replace the broken image with a fallback image. I've tried changing state, as well as an inline onerror function. None of those will work for me. WOuld anyone has a fix for this issue. This is what my component looks like:
const VerifiedLogo = ({ src, alt, isVerified }) => (
<div className={styles.logo}>
<img src={src ? src : '/images/icons/tournament-logo-placeholder.png'} alt={alt} onError="this.src='/images/icons/tournament-logo-placeholder.png'" />
<VerifiedBadge isVisible={isVerified} />
</div>
);
export default VerifiedLogo;
onError expects a function, in the constructor:
this.state = {
logoOk: false
}
in the render:
<img src={this.state.logoOk ? src : altLink} onError={()=>this.setState({logoOk: false})}/>

Resources