I am trying to include videos in my react project for that I am using ReactPlayer by cookpete.
Now the problem is it doesn't correctly parses or make us of, whatever, the url of the video inside the browser's html video tag where in the src attribute I can see src(unknown) is written. The weird thing is it once in a while behaves normally as it is expected to do. When I change the src attribute's value to the video's URL manually by inspecting the browsers html it starts getting played and I can do normal stuff with it. Here is the code which I have written.
<ReactPlayer
playing={isPlaying}
url="https://media.w3.org/2010/05/sintel/trailer_hd.mp4"
width="100vw - 69vw"
height="100vh - 65vh"
/>
The isPlaying stuff is a boolean which is being mantained inside React.useState() with intial value set to false.
The issue is a bug with React.StrictMode. A url with .mp4 extension isn't reloaded on the second reload induced by StrictMode.
Related
I have a GatsbyImage / StaticImage component and I use the onLoad event to trigger an animation. But once the browser has cached the image, the onLoad event never fires again. So if you visit a different page and then return, the animation isn't triggered.
The usual workaround with an ordinary image would be to attach a ref and then check ref.current.complete to see if the image had loaded. But GatsbyImage refuses to take a ref.
So
Is there any way to add a ref to the GatsbyImage component?
Is there any other way to detect if the image has loaded?
Is the only alternative to use an ordinary img tag (and lose out on all the gatsby image magic)?
Is there any way to add a ref to the GatsbyImage component?
Apparently, you can't. According to this GitHub thread it throws the following exception:
Function components cannot be given refs. Attempts to access this ref
will fail. Did you mean to use React.forwardRef()?
That said, you can try using forwardRef() which will give you a valid scope for your use-case.
Is there any other way to detect if the image has loaded?
Not directly. However, you can try the onStartLoad callback which expose the wasCached boolean that gives your more information and control about the browser cache. You can play around with that boolean to trigger the animation again or to use the value globally along with a useState for example:
<GatsbyImage
fadeIn={false}
className="customImg"
onLoad={() => {
// do loading stuff
}}
onStartLoad={({ wasCached }) => {
// do stuff on start of loading
// optionally with the wasCached boolean parameter
}}
onError={(error) => {
// do error stuff
}}
/>
Is the only alternative to use an ordinary img tag (and lose out on all the gatsby image magic)?
You can find a bunch of dependencies to lazy-load, fade, blur, get background primary color, etc of an image but its implementation, behavior, and compatibility will rely on the library itself. So, yes, there are alternatives but I'm not sure if they are worth it.
How can I set a default image for an img tag in case src link is invalid in react?
I've tried using onerror like so, but it doesn't seem to work.
Im using Next.js and hooks.
<img alt="Site Logo" src="/secondary.jpg" onerror="this.onerror=null; this.src='https://static.thenounproject.com/png/140281-200.png';" />
By invalid, I mean when the src receives a URL and it can't find an image I would like to make it display a default image.
When it can't find an image it will display this
Instead of this, I would like to make it display a default image if it can't find the image from the URL provided.
Usually, this can be done with onerror like above but it doesn't work in react for some reason, whats the alternative solution?
I was facing this issue and couldn't find a working solution anywhere, but I was able to understand an easy one. You can simply do this.
First, you can use useState like this and give your intended image.
const [imgSrc, setImgSrc] = useState("Invalid Image Source");
then, in your image component, you can simply do this. (make sure to spell onError correctly)
<img src={imgSrc} onError = {() => setImgSrc("https://picsum.photos/200")} />
in the setImgSrc() give the image you want as the default.
Hope this was helpful!
Is there a way to preload every image before showing the page to a user in Gatsby? Let's say that I want to avoid any preload effect that Gatsby is offering.
I am also wondering how I can force images that are not visible to preload. This is a major problem which I am trying to solve. Please take a look: https://festive-bassi-ce307b.netlify.app/.
If you try using the carousel then the next image that shows up will start preloading because it never was shown. This is really silly because at that point the whole page is loaded and the images as well.
I am using the gatsby-plugin-image and it's a staticImage component.
Example:
<StaticImage
className="img1 img"
src="../images/era_of_manufacturing_ilustrations/work_planning.png"
alt="work planning image"
placeholder="blurred"
layout="constrained"
quality={100}
/>
I also saw that the older gatsby-image plugin had a "loading" property that you could set to eager load. Could that property solve my problem?
Is there a way to preload every image before showing page to user in
Gatsby?
This is what eager attribute (from loading property) does according to the docs:
Loading behavior for the image. You should set this to eager for
above-the-fold images to ensure they start loading before React
hydration.
If you add:
<StaticImage
className="img1 img"
src="../images/era_of_manufacturing_ilustrations/work_planning.png"
alt="work planning image"
placeholder="blurred"
layout="constrained"
loading="eager"
quality={100}
/>
They will start loading before the rehydration process as if they were above-the-fold.
I don't understand the "preloading process" that you've pointed. Gatsby images are lazy-loaded by default but if you don't want to add a placeholder effect (the blurring), you can omit the placeholder property in the StaticImage.
Hello I am trying to use the react video js player but I am getting the error below:
The media could not be loaded, either because the server or network failed or because the format is not supported.
At first, I thought maybe it was the video type because Initially it was a .mkvi video I then changed to mp4 and still nothing I get the same error can I please get help
Code Below: VideoList.js
import React from 'react';
import VideoPlayer from 'react-video-js-player';
const VideoList = (props) =>{
let videos = props.listVideos
return(
<div>
{videos.map(video =>{
return(
<div key={video.id}>
<h3>{video.lecturer}</h3>
<VideoPlayer src={video.video} width="720" height="420" playbackRates={[0.5, 1, 3.85, 16]}/>
</div>
)
})}
</div>
)
}
export default VideoList
Like I said on my comments, typically this error will occur if the video is not existing, has issues with the encoding, file extension, etc. See this example I've written.
In the end, I was correct and the video.video object was returning a relative path instead of an absolute path which resulted in an incorrect link.
Regarding the OP's current solution for this issue, this is not an ideal architecture because it will probably fail when you deploy to production, switch domains, or even just switch ports. Concantenating your base url is fine (e.g., http://127.0.0.1:8000/) but I would have this variable as a single source of truth probably residing at a state at the topmost component or as an environment variable so that anytime you change domains, ports, or IP you can simply change this variable and you won't have to go through all of your components 1 by 1.
Example implementation on Class based components:
Parent component:
state = {
base_url: `http://127.0.0.1:8000/api/`, // local dev api
// base_url: `https://production-server:80/api/` // live site api
// or an environment variable as described on my answer
}
Child component:
<VideoPlayer src={`${this.props.base_url}${content.video}`}
So I managed to find the problem behind this, so I was getting data from the API but when I tried to access the video the API was not giving the full URL that is:
http://127.0.0.1:8000/media/lectures/<here_the_name_of_the_lecture_video>
But the API was giving me a relative path media/lectures/<here_the_name_of_the_lecture_video>
So I had to give the remaining the URL that which the API does not give when I render in the video i.e I had to write the following
<VideoPlayer src={`http://127.0.0.1:8000/api${content.video}`}
So I am wondering
Currently, this solution works but is this solution technically good? Because I am to believe that the API should be giving everything that I need I just have to make requests.
Can you please assist me to come up with a more technically viable solution for this problem
I would like to implement an export function on my SPA, consisting on generating a bunch of SVGs (generated using React JSX) and downloading them one at once.
The number of files being huge, I can't display them at the same time on the browser. I have found React Download SVG which permits to download a SVG which is already inthe DOM.
However, the render pipeline of React does not enable me to batch the downloading because I don't control the display cycle of my JSX SVG.
How could I download all my SVGs (zipping them in a file would be an advantage) without displaying them ?
Thanks in advance,
I worked with similiar problem - generate parametrized SVG paths for CNC purpose.
Problem wasn't with download as invoked manually (after DOM update) - batch download (zipped) planned, also.
Problem was: how to display SVG source/xml in another node/component for debugging - updated on every parameter change.
However, the render pipeline of React does not enable me to batch the downloading because I don't control the display cycle of my JSX SVG.
This is true ... is nome sense, even harder while React Fiber can delay some DOM updates - but we have some possibilities to be notified.
componentDidUpdate() - but 'not called for the initial render'
ref callback - but '... defined as an inline function, it will get called twice during updates, first with null and then again with the DOM element'
I prefer 2nd method for a few reasons, f.e. neutral to SVG (functional) component internals - however it's not guaranteed to be called in every use case - it won't be if not needed - OTOH CDM and CDU are guaranteed to have updated/proper refs when called.
Another hint found somewhere (SO?): use setTimeout to be safe/sure callback called after DOM update.
downloadableReference = el => {
console.log("DWNLD_REF ",el);
this.svgElement = el // save in wrapper, prevent old ref usage
if( !!el ) { // not null - second pass, fresh, updated
console.log("DWNLD_REF ready ", el.outerHTML )
setTimeout( ()=>{
this.notifyDownloadableDependants() // safest way - will be called after CDU
}, 0 )
}
}
This can be combined to batch the downloading. For UX I would render them sequentially - with progress visualisation, cancellable processing etc.
Another possibility: - maybe (not tested) use of react-jsx-parser be helpfull?