I'm trying to create a page in my React Js project, with the content on the left side and content's image on the right side. So far, I was able to create a toggle function that changes text and image according to the selected title, so, for example, if a user clicks title 1, text1 & image1 will be displayed, and when the user clicks title2, text2 & image2 will be rendered and etc. The problem is that images don't load until a title was clicked, but I need to display img1 when page loads for the first time(and then img1 should change to img2 or img3, depending on the clicked title).
codesandbox
My code:
import React, { useState } from "react";
import "./styles.css";
const data = [
{
id: "1",
key: "1",
title: "Title1",
text: "Text1.",
img: "1.jpg"
},
{
id: "2",
key: "2",
title: "Title2",
text: "Text2.",
img: "2.jpg"
},
{
id: "3",
key: "3",
title: "Title3",
text: "Text3.",
img: "3.jpg"
},
{
id: "4",
key: "4",
title: "Title4",
text: "Text4",
img: "4.jpg"
}
];
export default function App() {
const [toggled, toggle] = useState("");
return (
<div className="App">
{data.map(({ title, text, key, img }) => {
return (
<>
<div className="main">
<div className="text">
<h1 onClick={() => toggle(key)}>{title} </h1>
{toggled === key ? (
<>
<p>{text}</p>
</>
) : null}
</div>
<div className="img">
{toggled === key ? (
<>
<img src={img} key={key} className="photo" />
</>
) : null}
</div>
</div>
</>
);
})}
</div>
);
}
This is how the page is displaying on load now
This is how I want the page to be on load(with img1 being displayed)
What I would love to do is when the page is loaded, it should display img1, but when the user clicks title2, img1 should change to img2, any suggestions will be greatly appreciated,
Thank you.
I did a bit of refactoring for you, try this: https://codesandbox.io/s/toggle-kc3q2
I set the initial state to be "1" and using toggle and setToggle as the state and state setter
I'm posting my solution here, in case anyone else stumbles upon a similar problem. I added the following lines of code to my project:
***const [visible, setVisible] = useState(true);***
<h1 onClick={() => {
setToggle(key);
***setVisible(false);***
}}>
<div className="img">
***{visible && key === "1" ? (
<img src={img}
key={key}
/>)
: null}***
</div>
codesandbox
In this case, when the page is loaded, it displays img1 and only titles(without their texts), and only when a user clicks any title, a text, and its image is displayed.
Related
My image is not showing in React app. I am trying to fetch the path from JSON and pass the path using props in <img> tag.
Example JSON object with the product data:
let data = [
{
id: 1,
name: "Striped Slim Fit Shirt",
image: "./Assets/m1.jpg",
price: 1000,
category: "Men",
size: "XL",
inStock: true,
},
{
id: 2,
name: "Full Sleeves Slim Fit Shirt",
image: "./Assets/m2.jpg",
price: 2000,
category: "Men",
size: "L",
inStock: true,
},
];
export default data;
My parent component from which I am passing props.
import { Fragment } from "react";
import data from "../../DUMMY_DATA";
import ItemList from "./ItemList";
const HomePage = () => {
const availableItems = data.map((products) => (
<ItemList
key={products.id}
images={products.image}
name={products.name}
price={products.price}
category={products.category}
size={products.size}
/>
));
return (
<Fragment>
<div>{availableItems}</div>
</Fragment>
);
};
export default HomePage;
My child component. Here, console logging shows the correct path, but the <img> tag is not rendering it.
import { Fragment } from "react";
const ItemList = (props) => {
const { id, images, name, price, category, size, inStock } = props;
return (
<Fragment>
<div className="container text-center">
<div className="row row-cols-4" key={id}>
<div className="col">
<img src={images} />
</div>
<div className="col">{name}</div>
<div className="col">{size}</div>
<div className="col">{price}</div>
</div>
</div>
</Fragment>
);
};
export default ItemList;
I am using react slick in my Websites. I have 4 slides. Every Slide, I want a onClick Function to get the value. But When I click on the Slide, I am getting the last value only. I searched Stack Overflow but can't find solutions.
Here's the Code:
const productSlideImg = [
{ Img: prodImg1, ImgName: "img1", pageLink: "/home" },
{ Img: prodImg2, ImgName: "img2", pageLink: "/about" },
{ Img: prodImg3, ImgName: "img3", pageLink: "/contact" }
];
const handleClickSlide = (item) => {
console.log(item); // getting "img3" only on every slide click
};
<Slider
autoplay={true}
slidesToShow={1}
slidesToScroll={1} >
{productSlideImg.map((item, index) => (
<div >
<img
style={{ borderRadius: "50px" }}
width={"100%"}
src={item.Img}
onClick={() => {handleClickSlide(item.ImgName) }}
/>
</div>
))}
</Slider>
Please help me with some solutions
you have created a different function handleClickProduts
and using different function on img onClick
onClick={() => {handleClickProduts (item.ImgName) }}
CodeBox link: working code
I am using the data from below to pass as props in React. Everything works fine but I need to only bold the words "target audience" in the text property. Is there a way to do this?
const SlideData = [
{
index: 1,
title: "Target Audience",
text: [
"The target audience for this course is anyone who is assigned roles as a HR Employee Maintainer...",
],
image: {
src: targetAudience,
width: imageSize,
},
},
index: 2,
title: "Reporting ",
text: [
"Reporting Manager is designated to...",
],
image: {
src: reporting,
width: imageSize,
},
},
]
export default SlideData
Added Render Component
const TextSlide = ({ title, text = [], list, image }) => {
return (
<>
<div className="slide">
<div className="standard-grid">
<span className="slide-title title">{title}</span>
<div className="content">
{text.map((t, i) => (
<p key={i} className="text">
{t}
</p>
))}
</div>
{image ? <img className="picture" src={image.src} style={{ maxWidth: image.width }} alt="image" /> : null}
</div>
</div>
</>
);
};
export default TextSlide;
``
You could split the text by target audience, and map the chunks inbetween to text nodes appending a node to each element:
"The target audience for this course is anyone who is assigned roles as a HR Employee Maintainer...",
.split("target audience")
.map((text, index) => <>{index !== 0 && <b>target audience</b>} {text}</>)
A more sophisticated approach would be to inject html tags into the text, and use dangerouslySetInnerHTML:
const formatted = text.replace(/(target audience)/g, it => `<b>${it}</b>`);
return <div dangerouslySetInnerHTML={formatted} />;
You could change the text to an object with a key of __html and use bold tags to render it by using dangerouslySetInnerHTML:
const SlideData = [
{
index: 1,
title: "Target Audience",
text: [
{
__html:
"The <b>target audience<b> for this course is anyone who is assigned roles as a HR Employee Maintainer...",
},
],
image: {
src: targetAudience,
width: imageSize,
},
},
];
const TextSlide = ({ title, text = [], list, image }) => {
return (
<>
<div className="slide">
<div className="standard-grid">
<span className="slide-title title">{title}</span>
<div className="content">
{text.map((t, i) => (
<p key={i} className="text" dangerouslySetInnerHTML={t} />
))}
</div>
{image ? (
<img
className="picture"
src={image.src}
style={{ maxWidth: image.width }}
alt="image"
/>
) : null}
</div>
</div>
</>
);
};
Here is a small codepen for demonstration.
Try this:
text: ["The ", <strong>target audience</strong>, " for this course is anyone who is assigned roles as a HR Employee Maintainer..."]
React will render this as a string with the HTML tags applied.
I'm having issue where when i put my state into index of an array, it gives error.
Here is there line of bug : {WorkData[state].title}
What i need to do is to display the elements of WorkData which is a array with objects : title, content, img math etc...
const WorkData = [
{
id: 0,
title: 'title',
subtext: 'React/Express',
content: 'content',
imgPath: 'imgPath',
},
{
id: 1,
title: 'Little Hero Academy',
subtext: 'React/API REST',
content:
'content,
imgPath: 'imgPath',
},
{
id: 2,
title: 'title',
subtext: 'subtext',
content: 'content',
imgPath: 'imgPath',
},
First, i have a list of cards with a button that contains data:
<div className="work-container flex">
<div className="work-bloc zoom">
<div className="work-hover" />
<div className="work-text">
<div className="text-title">{WorkData[0].title}</div>
<span className="subtext">{WorkData[0].subtext}</span>
</div>
<div
onClick={togglePopup}
data-id={WorkData[0].id}
className="work-showmore button2"
>
Show More
</div>
</div>
</div>
I store the data in state with this function :
const [id, setId] = useState();
const togglePopup = (e) => {
setIsOpen(!isOpen);
setId(e.target.dataset.id);
};
I need that data to get to the popup,
<Popup
togglePopup={togglePopup}
closePopup={closePopup}
isOpen={isOpen}
id={id}
/>
I pass the state to my popup component and try to display the value of id which is displayed
Also,i need to make the popup display of the content of the array that belong to the id (index) i passed in state : workData 1 2 3 etc...
const Popup = ({ closePopup, isOpen, id }) => {
return (
<div className={`popup-container ${isOpen ? 'opened' : 'closed'}`}>
<div className={`popup ${isOpen ? 'opened2' : 'closed2'}`}>
<span className='popup-title'>
{WorkData[id].title}
{id}
</span>
<div className='image-container'>
<img
src='https://i.picsum.photos/id/1060/536/354.jpg?blur=2&hmac=0zJLs1ar00sBbW5Ahd_4zA6pgZqCVavwuHToO6VtcYY'
alt=''
/>
</div>
<p>
Team projet with React and API REST. Our goal was to make an app with
a choosen API and make something out of it. We did a superhero-themed
website with games for children.
<br />
Check on <AiFillGithub className='menuicon' />
</p>
<div onClick={closePopup} className='close-icon button2'>
Show less{' '}
</div>
</div>
</div>
);
};
but i get this error :
**TypeError: _WorkData__WEBPACK_IMPORTED_MODULE_1__.default[id] is undefined**
Thanks in advance for any suggestion
Ok i fixed, it i changed the way of doing it, i mapped my workcard components so i can easily retrieve the id, title, etc, and i didnt change the event onclick to catch the card.id in state, i passed the state to parent, then to the popup, and then into the popup component i just imported the WorkData.js and simply did : WorkData[state-with-id].title etc
See sample of code below
works.js
const togglePopup = (e) => {
setIsOpen(!isOpen);
setPopupId(e.target.dataset.id);
};
const closePopup = () => {
setIsOpen(false);
};
useEffect(() => {
setCards(workData);
}, []);
workcards.js
<div
onClick={togglePopup}
className='work-showmore button2'
data-id={workcard.id}
>
popup.js
import workData from './workData';
<span className='popup-title'>{workData[popupId].title}</span>
I am working on a web app in the ReactJS framework and I'm using react-slideshow-image component for a simple slideshow. However due to how the component works, I can only render the images. I would like to add a short description for each image and have it appear with it. Is there a way to modify this code to render a description under the image? (I was thinking about useEffect hook but I'm not sure.)
const Slideshow = () => {
return (
<SlideContainer>
//styled component
<Zoom scale={0.4}>
//Zoom component comes from react-slideshow-image
{
slideshowImages.map((each, index) => <img key={index} style={{padding: "0", margin: "0", width: "20vw"}} src={each} />)
}
</Zoom>
</SlideContainer>
)
};
Try this behavior, Here you can show the description on the image.
const images = [
{
id: "img1",
url: "../images/image-1.png",
description: "image 1 description here"
},
{
id: "img2",
url: "../images/image-2.png",
description: "image 2 description here"
}
];
const Slideshow = () => {
return (
<div className="slide-container">
<Zoom {...zoomOutProperties}>
{images.map((each, index) => (
<div
style={{
background: `url(${each.url}) no-repeat`,
width: "300px",
height: "240px"
}}
>
<b>{each.description}</b>
</div>
))}
</Zoom>
</div>
);
};
Hope you are looking for the same use case.
Working demo:- https://codesandbox.io/s/modest-proskuriakova-28qsk?file=/src/App.js
This wasn't quite what I wanted but it pointed me in the right direction. Here's my solution inspired by yours and official React documentation:
const slideshowImages = [
{
id: 1,
image: "/imageUrl",
desc: //description
},
//as many elements as you want
]
const Slideshow = () => {
//SlideContainer and DescriptionWrapper are styled components
return (
<SlideContainer>
<Zoom {...zoomOutProperties}>
{
slideshowImages.map(
(slide) =>
<div key={slide.id}>
<img style={{padding: "0", margin: "0", width: "20vw"}} src={slide.image} />
<DescriptionWrapper>{slide.desc}</DescriptionWrapper>
</div>
)
}
</Zoom>
</SlideContainer>
)
};
export default Slideshow;
Thanks a lot, I wouldn't have thought of something like this.