my image is not showing up ReactJS Template component - reactjs

I am making a news section for my website. I am using a react template that will receive data from a "Data" file then reinsert it into the file that is put into my app.js file. Everything works except for the fact that the image I am using does not work and defaults to it's alt text. below is the code for all files involved.
This is the template code
import React from 'react'
import './News.css'
function NewsContentTemplate ({
title,
date,
content,
img,
imgStart,
alt,
}) {
return (
<>
<div className='nct-container'>
<div className='row content-container'
style={{display: 'flex',
flexDirection:
imgStart === 'start' ? 'row-reverse' : 'row',
}}>
<div className='col'>
<div className='content-text-wrapper' >
<h2 className='content-date'>{date}</h2>
<h2 className='content-title'>{title}</h2>
<p className='news-content'>{content}</p>
</div>
</div>
<div className='col'
style={{
display: 'flex',
justifyContent:
imgStart === 'start' ? 'flex-end' : 'flex-start'}}>
<img src={img} alt={alt} className="news-img" />
</div>
</div>
</div>
</>
)
}
export default NewsContentTemplate
This is the "Data" file that passes information into the template. The image is being taken from an "images" folder in the public folder of my app.
export const jun302022 = {
imgStart: '',
title: 'Title',
date: '6-30-2022',
content:
'content',
img: './images/logo192.png',
alt: 'alt text'
}
This is the code that imports the template and passes it to app.js
import React from 'react'
import Content from '../../NewsContentTemplate'
import {
jun302022,
} from './Data'
function News () {
return (
<>
<div className='news-container' id='news'>
<h1 className='news-section-title'>
News
</h1>
<Content {...jun302022}/>
</div>
</>
)
}
export default News
the code should look like This but ends up looking like This
Thank you.

Related

React: I don't see thumbnails when using react-responsive-carousel

I have followed the demo code and all works well except thumbnails. I set it to true so I can see 'ul' for the thumbnails in html, but it does not have any image src.
Here is the code below.
import React from 'react';
import { Carousel } from 'react-responsive-carousel';
import 'react-responsive-carousel/lib/styles/carousel.min.css';
import Image from 'next/image';
const Banner = ({ carousel, isDifferent, className }) => {
return (
<div>
<Carousel autoPlay infiniteLoop showThumbs>
{carousel.length !== 0 &&
carousel?.map((item, idx) => (
<div className={`relative w-full ${className} cursor-pointer`} key={idx}>
<Image src={isDifferent ? item?.node?.mediaItemUrl : item.node.bannerInfo.bannerImage.mediaItemUrl} alt="banner" objectPosition="center top" layout="fill" objectFit="cover" priority />
</div>
))}
</Carousel>
</div>
);
};
export default Banner;
This is how I use Banner component
<Banner carousel={product.galleryImages.edges} isDifferent className="md:hidden h-[400px]" />
When I check on the development tool, I see the ul.
Please let know what I am missing.
If not using the img html element directly you need to render the thumbnails with renderThumbs
example:
renderThumbs={() =>
mThumbnails.map((thumbnail) => (
<Image src={thumbnail.src} alt={thumbnail.alt} key={thumbnail.src} />
))
}

react component not working properly when rendered multiple times

Given below is code of a react component(Newsitem) and I have passed title as props through API. In Newsitem there is a span tag which I need to make hidden when the title passed in Newsitem contains less that 70 characters. But that doesn't happen, what happens is that whenever title has less than 70 characters so the span tag of first newsItem which was rendered get hidden and not of that newsitem to which that title belonged
export class NewsItem extends Component {
state = {
title: true
}
componentDidMount(){
let readTitle = document.getElementById('readTitle')
if(this.props.title.length<70){
readTitle.style.visibility = 'hidden'
console.log('Done....');
}
console.log('componentDidMount() lifecycle');
this.setState({title : !this.state.title})
}
render() {
console.log('Render lifecycle');
let {title , description , imageURL , newsURL} = this.props;
return (
<>
<div>
<div className="card" style={{width: '18rem'}}>
<img src={imageURL} className="card-img-top" alt="..."/>
<div className="card-body">
<h5 className="card-title" style={{display: 'inline'}} id='title'>{title}</h5>
<span id='readTitle'><b>Read More</b></span>
<p className="card-text">{description}</p>
Read More
</div>
</div>
</div>
</>
);
}
}
export default NewsItem;
Further to my comment, I would probably use a stateless functional component, and the React.useRef hook and do something like this:
import React, {useRef, useEffect} from 'react';
const NewsItem = ({title , description , imageURL , newsURL}) => {
const readTitle = useRef(null);
useEffect(()=>{
if(title.length<70){
readTitle.current.style.visibility = 'hidden'
console.log('Done....');
}
}, [title])
return (
<div>
<div className="card" style={{width: '18rem'}}>
<img src={imageURL} className="card-img-top" alt="..."/>
<div className="card-body">
<h5 className="card-title" style={{display: 'inline'}} id='title'>{title}</h5>
<span ref={readTitle}><b>Read More</b></span>
<p className="card-text">{description}</p>
Read More
</div>
</div>
</div>
);
};
export default NewsItem;
Should work as expected, and is considerably more concise :)
There is a very important rule in react and it is to not use js dom functions in the middle of components. If you use them you can create conflicts between components and states. You can instead use React refs in this case.

Working with images local files in Gatsby.js

I am trying to render a headshot for each artist displayed on the page. The artist data comes from a Json file, and the images are located in images/artists/headshots. I am using the regular img tag, but for some reason nothing is displaying on the page. Any help any one can give would be greatly appreciated.
import React from 'react'
import PropTypes from 'prop-types'
import { StaticImage } from 'gatsby-plugin-image'
import { useStyles } from './styles'
const ArtistsPage = ({ data }) => {
const classes = useStyles()
return (
<section>
<article className={classes.artistsBackground}>
<div className={classes.heroLayoutContainer}>
<h3 className={classes.title}>MEET THE ARTISTS</h3>
<StaticImage
className={classes.heroImage}
src='../../images/artists/hero-images/hero-image-artists.jpg'
alt='hero-image-artists'
placeholder='blurred'
/>
</div>
</article>
<article className={classes.artistsContainer}>
<div className={classes.flexContainer}>
{data.allArtistsJson.edges
.map(({ node }, idx) => {
const artist = `${node.firstName}+${node.lastName}`
.split('+')
.join(' ')
return (
<div className={classes.flexItem} key={idx}>
<div>
<img
src={`../../images/artists/headshots/${artist} Headshot.jpg`}
alt='artist-headshot'
/>
</div>
<div className={classes.artistCardName}>
{`${node.firstName} ${node.lastName}`.toUpperCase()}
</div>
<div className={classes.artistCardText}>{node.city}</div>
<div className={classes.artistCardText}>
{node.currentTeam}
</div>
</div>
)
})}
</div>
</article>
</section>
)
}
export default ArtistsPage
My image files are set up as:
FirstName LastName Headshots.jpg
I think your issue may comes from the white spaces in the naming. Your code looks good at first sight so try renaming your images with underscore or in camelCase:
<img
src={`../../images/artists/headshots/${artist}_Headshot.jpg`}
alt='artist-headshot'
/>
After much research and the nice people on Gatsby discord I found the answer to be… in a scenario like this I needed to add require().default.
Ex:
<img
src={require(../../images/artists/headshots/${artist} Headshot.jpg).default}
alt='artist-headshot'
/>

Caching in Gatsby JS

I have this Gatsby app where when I visit home page everything loads at first including the Testimonials section. However, when I visit another page, for instance the Blog list page and then click on the link back to homepage the data on Testimonials component won't load and you will see a blank area of the app where the Testimonials section is placed. In order to see the Testimonials list, you will have the refresh the page again.
For the record the data on my Testimonials component are being pulled out on Strapi JS that is deployed on Heroku.
So far I got this on my index.js:
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/Layout"
import Header from "../components/Header"
import Testimonials from '../components/Testimonials'
import Blogs from '../components/Blogs'
import SEO from '../components/SEO'
export default function Home({ data }) {
const {
allStrapiBlogs: { nodes:blogs },
} = data
return (
<>
<SEO />
<div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
</>
)
}
export const query = graphql`
{
allStrapiBlogs(filter: {featured: {eq: true}}, sort: {fields: published_date, order: DESC}, limit: 6) {
nodes {
id
title
content
slug
published_date(formatString: "MMMM DD, YYYY")
featured_image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`
And then on my Testimonials.js component:
import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import Image from "gatsby-image"
import { FaStar } from "react-icons/fa"
import Title from './Title'
const query = graphql`
{
allStrapiTestimonials {
nodes {
id
name
cite
text
photo {
childImageSharp {
fluid{
...GatsbyImageSharpFluid_withWebp
}
}
}
}
}
}
`
const Testimonials = ({ title }) => {
const data = useStaticQuery(query)
const { allStrapiTestimonials: { nodes:testimonials } } = data
return (
<div className="testimonial-section section-padding" id="testimonial" data-aos="zoom-in">
<div className="container">
<div className="row">
<div className="col-lg-12">
<div className="section-title-two center">
<Title title={title} />
</div>
</div>
</div>
<div className="testimonial-wrap row">
<div className="testimonial-slider owl-carousel">
{ testimonials.map(item => {
const { id, name, cite, text, photo } = item
return(
<div className="col-xl-8 col-lg-10 col-12 ml-auto mr-auto" key={id}>
<div className="testimonial-item mt-40">
<div className="testimonial_img">
<Image fluid={photo.childImageSharp.fluid} alt={name} style={{ position: "absolute", overflow: "visible", display: "block", width: "211px", height: "207px" }} />
</div>
<div className="testimonial_content xs-mt-40">
<div className="testimonial_content_item mb-30">
<div className="testimonial_content__pro">
<h4 className="mb-10">{ name }</h4>
<p>{ cite }</p>
</div>
<ul className="d-none d-sm-inline-block">
<li><FaStar></FaStar></li>
<li><FaStar></FaStar></li>
<li><FaStar></FaStar></li>
<li><FaStar></FaStar></li>
<li><FaStar></FaStar></li>
</ul>
</div>
<div>
<p>{ text } </p>
</div>
</div>
</div>
</div>
)
})}
</div>
</div>
</div>
</div>
)
}
export default Testimonials
Any idea what's causing this error? How can I fix it?
I've faced a similar issue a few months ago and the fix depends strictly on the implementation and your code. Basically, what is happening is that React's doesn't understand that he needs to rehydrate some components because pointing to some global objects as window or document of the DOM, outside the React's ecosystem (without using states) may block that rehydration, in your cause, because of jQuery.
All the possible solutions that bypass this issue will be patches (like trying to add the cache). The ideal solution would avoid using jQuery, which points directly to the DOM, with React, which manipulates the virtual DOM (vDOM).
There's nothing wrong with the code you've shared, however, based on some other questions that you did, you are using jQuery and using the window object, which prevents the rehydration of some React components. You should get rid of jQuery or using some React-based approach. Something like this should do the trick to force a loader across the whole site:
const Layout = ({ children }) => {
const [loader, setLoader]=useState(true);
useEffect(()=>{
setTimeout(()=> {
setLoader(false)
}, 400)
}, [])
return <section className={`site__wrapper`}>
<Header />
<main>{loader ? <Preloader/> : children}</main>
</section>;
};

Best way to implement image enlargement on Thumbnails on Product Pages in Gatsby

List item
My product thumbnails don't enlarge on click using gatsby-remark-images-medium-zoom#1.2.1 or gatsby-remark-images-zoom
Followed readme on both and declared plugins in gatsby-config, also tried experimenting with option configurations. To see what I mean here's an example: https://store.shaka-surf.com/products/eco-medium-g5-surf-fins
import React from 'react'
import Img from 'gatsby-image'
import { graphql, useStaticQuery } from 'gatsby'
export default function Thumbnails({ src }) {
const { allMoltinProduct } = useStaticQuery(graphql`
query allMoltinProductsQuery {
allMoltinProduct {
nodes {
id
images {
childImageSharp {
sizes(sizes: "max-width: 801px) 100vw, 801px") {
srcSet
sizes
}
}
}
}
}
}
`)
return (
<div className="thumbnail-container">
{allMoltinProduct.nodes.map(product => (
<React.Fragment key={product.id}>
{product.images.map((image, index) => (
<ul className="thumbnail-list">
<li key={`image-${index}`} style={{display: 'inline-block', float:
'none', color: '#F2F4F5', width: '44px', height: '44px'}}>
<Img fluid={image.childImageSharp.fluid.src}
/>
<img sizes={image.childImageSharp.sizes.sizes} src=
{image.childImageSharp.fluid.src} srcSet=
{image.childImageSharp.sizes.srcSet} className="thumbnail-image medium-zoom- image" loading="lazy" alt={product.name} />
>
</li>
</ul>
))}
</React.Fragment>
))}
</div>
)
}
Would like the product thumbnails to enlarge.
UPDATE: managed to get Lightbox from this repo working on my gallery which is good enough for now. Will come back to the thumbnails at a later date.

Resources