Why is my react-lazyload component not working? - reactjs

Up until a few days ago, my implementation of LazyLoad was working perfectly, but now I can't seem to get it to work.
This is my component:
import React from 'react';
import LazyLoad from 'react-lazyload';
import './image.scss';
const Image = image => (
<LazyLoad height={200} offset={100} once>
<div
className="image-container"
orientation={image.orientation}>
<img
className="image"
src={image.url}
alt={image.alt}
/>
{'caption' in image &&
<div className="meta">
<p className="caption">{image.caption}</p>
<p className="order">{image.currentNumber}/{image.maxNumber}</p>
</div>
}
</div>
</LazyLoad>
)
export default Image
And in App.js it is called like this:
render() {
return (
<div className="wrapper">
<GalleryTop details={this.state.gallery_top} />
{this.state.images.map((image, index) => <Image key={index} {...image} /> )}
</div>
)
}
But it won't work! Here's the demo environment:
https://gifted-kare-1c0eba.netlify.com/
(Check Network tab in Inspector to see that images are all requested from initial load)
There's also a video here
Any idea about what I am doing wrong?
Thanks in advance,
Morten

I ran into similar issues with the npm package react-lazyload. For one, this package only allows one child per LazyLoad component, so you would have to rearrange your hierarchy to make it work. Secondly, I found some strange behaviors when loading images that were already set within the viewport. The documentation does list import {forceCheck} from 'react-lazyload'; combined with forceCheck(); as a means of manually checking the elements, but I found this inconvenient and insufficient for components that aren't rerendering.
I was able to obtain the exact same functionalities with an easier implementation from the alternative package react-lazy-load. Mind the hyphen. This package also requires node>0.14. More or less, it does the same thing. You can read their documentation here: react-lazy-load

Related

Can't get tiny-slider-react functionality to work

Can't get the npm package tiny-slider-react to work. Probably doing something basic wrong. It imports just fine without any errors, but it only displays the loadingimages without any functionality, just as if the images would be if you'd do <img />. The code is straight from the npm read me file.
import TinySlider from "tiny-slider-react";
import 'tiny-slider/dist/tiny-slider.css';
export default function Testimonials() {
const settings = {
lazyload: true,
nav: true,
mouseDrag: true
};
const imgs = [
"https://source.unsplash.com/random/200x400",
"https://source.unsplash.com/random/200x400",
"https://source.unsplash.com/random/200x400",
"https://source.unsplash.com/random/200x400",
];
const loadingImage = "https://source.unsplash.com/random/100x100"
return (
<section className='h-screen bg-white dark:bg-gray-700'>
<TinySlider settings={settings}>
{imgs.map((el, index) => (
<div key={index} style={{ position: "relative" }}>
<img
className={`tns-lazy-img`}
src={loadingImage}
data-src={el}
alt=""
/>
</div>
))}
</TinySlider>
</section>
)
}
I expected it to work like the examples https://codesandbox.io/s/test-tiny-slider-react-forked-rmxcl?file=/index.js:752-784, here's one. I have installed the npm package and I don't think I get any errors in the browser console related to tiny slider. I tried using TinySlider just like OwlCarousel too, so basically just having <img /> props in the <TinySlider /> component, got the same issue.
Could it have something to do with the css file not importing correctly?
In React 18, it seems that TinySlider works normally when it is not wrapped in <StrictMode>.
Demo of the test: codesandbox
If <StrictMode> is still preferred in the same App, perhaps consider to enable it on other parts of the app, as recommended by React document.
TinySlider does not seem to have problems working in older versions of React, by the way.

Dynamic image src linking in react doesn`t work (multiple tries)

In my project I need to link a img src dynamically.
This is the whole project structure:
I have tried multiple ways to link up my imag src in the follwing component, as you can see in the out commented part of my code.
The path itself cannot be the problem because the third try, which I cannot use cause its not dynamic, works very well.
What am I doin wrong?
import React from 'react';
import * as CommentStyles from './comment.module.scss';
// Only this works
import Image from '../../../../assets/image-anne.jpg';
function Comment({comment}) {
return (
<div>
<div className={CommentStyles.firstRow}>
{/* first try - didn`t work*/}
{/* <img src={require('../../../../assets/image-anne.jpg')} /> */}
{/* second try - didn`t work*/}
{/* <img src={'../../../../assets/image-anne.jpg'}/> */}
{/* third try - didn`t work*/}
<img src='../../../../assets/image-anne.jpg'/>
{/* fourth try-works: */}
{/* <img src={Image}/> */}
<div className="firstFlexItem">
<div className="name Username">
{comment.user.name} <br/>
{comment.user.username}
</div>
</div>
<p>
Reply
</p>
</div>
</div>
)
}
export default Comment
I have now put the jpg in the public folder and it doesn`t work:
I'm assuming you have created your reactjs project using the create-react-app command.
Since you want to dynamically set the image src attribute, the workaround would be to add the image or images inside the public folder as advised here in the official documentation : https://create-react-app.dev/docs/using-the-public-folder/#when-to-use-the-public-folder
Then just use
<img src={`image-anne.jpg`} />
Where src has the path to your image relative to the public folder. This can also be dynamically set and will work just fine
NOTE : If this doesn't work, use
<img src={process.env.PUBLIC_URL + '/image-anne.jpg'} />
And make sure you kill the current session and restart your app using npm start or yarn start if you still can't see the image.
Screenshot from above link :

how to resolve "Prop `id` did not match. Server: "react-tabs-30" Client: "react-tabs-0" console issue?

i am trying tab in next in next.js, but every time i use it it show a console warning link this Prop `id` did not match. Server: "react-tabs-30" Client: "react-tabs-0", i know it isn't effect my app but it is so annoying. how to solve this waring
<Tabs>
<div className="tab-controler ml-sm-auto">
<TabList className="tab-lists list-inline d-flex flex-wrap nav mb-3" style={{ background: '#F8F8F8' }}>
<Tab className={`${CostCalculatorStyle.PEItem} tab-lists__item`}>Buy & Ship for me</Tab>
<Tab className={`${CostCalculatorStyle.PEItem} tab-lists__item`}>Ship for me</Tab>
</TabList>
</div>
<TabPanel key={"tabpanel_ship"}>
<div className="row">
<div className="col-lg-6">
<ShipForMeForm handleFormValue={handleFormValue} handleProductValue={handleProducts} handleRef={handleRef} />
</div>
<div className="col-lg-6 align-self-center">
<div className="costcalc-empty-thumb text-center">
<Image
src="/assets/topNavbarPages/costCalculator.svg"
alt="Cost Calculator"
width="469"
height="288"
/>
</div>
</div>
</div>
</TabPanel>
<TabPanel key={"tabpanel_buy_ship"}>
<div className="row">
<div className="col-lg-6">
<ShipForMeForm handleFormValue={handleFormValue} handleProductValue={handleProducts} handleRef={handleRef} />
</div>
<div className="col-lg-6 align-self-center">
<div className="costcalc-empty-thumb text-center">
<Image
src="/assets/topNavbarPages/costCalculator.svg"
alt="Cost Calculator"
width="469"
height="288"
/>
</div>
</div>
</div>
</TabPanel>
</Tabs>
as you can see i use react-tabs for tab but i also work on react js where i use the same code but it didn't show this console warning. so my question is why it is happing? and how i can solve it ?
In next js i fixed it like that
import dynamic from 'next/dynamic'
const Tabs = dynamic(import('react-tabs').then(mod => mod.Tabs), { ssr: false }) // disable ssr
import { Tab, TabList, TabPanel } from 'react-tabs'
it work for me
The best solution I know of is just to set the id yourself in the <Tabs> component. Ex: <Tabs id={1}>
See https://github.com/chakra-ui/chakra-ui/issues/4328#issuecomment-890525420 for more details and examples.
NextJs generating code in server side as you know.
This error means that something on the server is different from the Client. This can happen if the client does a re-render.
For example.
export default function Test(props) {
return (
<>
<span>{props.name}</span>
</>
);
}
I have this simple Test component.And I send name (1) prop from another component to this Test component. And if I change this name (to 2) in client using redux (for example I have another name in my redux store) after page generated I get this error.
props did not match server "1" client "2"
To solve this error I need to just not change this name with redux after page generated in server. The data can be change only with user manipulations after page rendered in server.
Same thing happened to me when I use Tabs from react-bootstrap. Koushik Saha's answer can be apply for that also but with a small change. Need to put react-bootstrap instead react-tabs
const Tabs = dynamic(import('react-bootstrap').then(mod => mod.Tabs), { ssr: false })
In case you miss it
If you are using Nextjs + Material-ui, there are actually custom codes that you can/need to include in your _document.js and _app.js to remove the server-side injected CSS so the CSS is recreated when page loads.
As codes changes with mui's and nextjs' version, i will refer you to the repository directly
https://github.com/mui-org/material-ui/tree/master/examples/nextjs/pages
As per the documentation in the react-tabs repo/npmjs.org page (https://www.npmjs.com/package/react-tabs):
import { resetIdCounter } from 'react-tabs';
resetIdCounter();
ReactDOMServer.renderToString(...);
I was having the same issue and called the resetIdCounter function inside my parent component to the tabs structure and cleared up the error.
Not sure if maybe there is a better place to use this function, like maybe in a useEffect hook or something, but I'm going with this for now.

React won't load images

I am building a react blog and my images won't load. It shows me this message in console - src\components\BlogPost\index.js
Line 21:11: Redundant alt attribute. Screen-readers already announce `img` tags as an image. You don’t need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the alt prop jsx-a11y/img-redundant-alt.
My source:
const BlogPost = (props) => {
return(
<div className="blogPostContainer">
<Card>
<div className="blogHeader">
<span className="blogCategory">Featured</span>
<h1 className="postTitle">..</h1>
<span className="postedBy">..</span>
</div>
<div className="postimageContainer">
<img src={require('../../blogPostimages/memories-from.jpg')} alt="Post image" />
</div>
</Card>
</div> )
}
Please help. Thank you.
<img src="example" aria-hidden alt="Picture of me taking a photo of an image" />
add "aria-hidden "
Redundant alt attribute warning doesn't prevent image loading. It means there is a meaningless alt in your image. alt attribute is useful for accessibility and must describe the image if the download fails.
Use an accurate description for images or alt="" for backgrounds and decorations.
Loading errors probably are caused by imports errors. Check image path, name, and location.
Here an example of an image import.
import logo from '../static/logo.png';
export default function Navbar() {
return (
<img src={logo} alt='website logo' />
)
}

Testing a component with no logic

Should you test components that have no logic? My component only renders jsx and some other components from a file above. Here's the example :
import React from 'react';
import SubscriptionForm from './SubscriptionForm';
import './style.scss';
import { FiPhone, FiMail } from 'react-icons/fi';
import { FaFacebook, FaTwitterSquare, FaLinkedin } from 'react-icons/fa';
export default function Footer() {
return (
<div className="footer-container">
<div className="footer-container__contact">
<h2>Contact us</h2>
<p>
<FiMail /> test#test.com
</p>
<p>
<FiPhone /> +31 6 - 1222 - 123
</p>
</div>
<div className="footer-container__subscription-form">
<h2>Subscribe and never miss a release</h2>
<SubscriptionForm />
</div>
<div className="footer-container__social">
<h2>Follow us</h2>
<div className="footer-container__social-icons">
<FaFacebook className="footer-container__social-icon" />
<FaTwitterSquare className="footer-container__social-icon" />
<FaLinkedin className="footer-container__social-icon" />
</div>
</div>
</div>
);
}
Should you test such components. All i can test is if it renders , right ? I've heard about snapshot testing , but i'm not sure if this is a case where i should use it.
I do not think that there is a right answer for that but think about the value of the test always from the user's point of view.
Are you planning to change this to support translations? so it would be a good test by snapshot or just checking the labels on the page.
Does the snapshot test make sense for your team? or they would just update when get some error?
But the most important from my point of view (and the user) would be the style, a CSS change would be able to break the style of this component so you could think to support visual tests focused only on the whole pages to cover those scenarios, it takes a real screenshot to compare the images.

Resources