Unable to render icon components in React - reactjs

I have a list of icons that i want to render out. I am new to react, please help.
below is my code
import { GlobeAltIcon, ComputerDesktopIcon } from '#heroicons/react/24/outline'
const icons = [
{
id: 1,
name: GlobeAltIcon
},
{
id: 2,
name: ComputerDesktopIcon
},
}
const App = () => {
return (
{icons.map((icon)=>(
<div key={icon.id}>
{icon.name}
</div>
))}
)
}
the code returns error whenever i try to render the icon components. Please help me out

Because it's an icon and a JSX, you have to render it like a component, like this:
const App = () => {
return (
{icons.map((icon)=>(
<div key={icon.id}>
<icon.name />
</div>
))}
)
}

You can use the icon inside the map like this
<icon.name/>

Related

I am not getting data of my useState through .map function in React Js

React Js
I am trying to display data through .map which is in react state object, but I am not getting data on browser with any error, yes I now that I am not write setState in this code because i want only display my data on my browser. if this problem will be solved then I will done my setState, I Think setState is not necessary for only showing data which is in State Object.
import React from 'react';
import TinderCard from 'react-tinder-card';
function TinderCards(){
const [people, setPeople] = React.useState([
{
name: 'steve jobs',
url: 'https://cdn.britannica.com/04/171104-050-AEFE3141/Steve-Jobs-iPhone-2010.jpg'
},
{
name: 'mark zukerberg',
url: 'https://cdn.britannica.com/54/187354-050-BE0530AF/Mark-Zuckerberg.jpg'
}
]);
return (
<div>
{
people.map(person =>{
<h1>{person.name}</h1>
})
}
</div>
)
// const people = [] same thing
// BAD
// const people = [];
// people.push('sonny', 'qazi')
// GOOD (push to an array in REACT)
// setPeople([...people, 'mathan', 'lal'])
}
export default TinderCards;
You don’t return anything from map.
Change your return section to this:
return (
<div>
{people.map(person => (
<h1>{person.name}</h1>
))}
</div>
)
or if you like to keep the curly brackets syntax:
return (
<div>
{people.map(person => {
return <h1>{person.name}</h1>
})}
</div>
)

React - implement a component as js api

I want to create a stack of toast messages in my app.
I dont want to re-draw the <Toast component over and over again.
My need is to call it as a function and it will render itself
Something like:
Toast.push({time: 5, message: 'Data was submitted', type: 'success'});
Toast.push({time: 2, message: 'Data was not processed yet', type: 'warn'});
This way I can manage the DOM array inside the component and it will be some sort of a singleton component. One instance for the entire app
Is it possible to call and display a component like: Toast.push(...);
Im using function based components with the latest react
Update
This concept is implemented in ant.design https://ant.design/components/message/ - message.warn('Some message').
I want to avoid props and contexts... It needs to be as simple as possible... Toast.push(...) that's it
Thanks
You can create a custom useToast hook, returning an element and a push function.
//App.js
import useToast from "./useToast";
export default function App() {
const { toast, push } = useToast();
return (
<div>
<p>Your stuff here</p>
{toast}
<button onClick={() => push({ message: "hi" })} />
</div>
);
}
//useToast.js
import { useState } from "react";
export default function useToast(initial = []) {
const [list, setList] = useState(initial);
return {
push(data) {
setList([...list, data]);
},
toast: (
<ul>
{list.map(({ message }, i) => <li key={i}>{message}</li>)}
</ul>
),
};
}

React Tinder Cards showing Hooks can only be called inside of the body of a function component

Problem:
Hi I'm a beginner in React JS, I was Following a YouTube Tutorial on making a Tinder Clone. I followed the exact steps but still got this error and I'm stuck here. I have searched almost everywhere but cant figure out what is the issue.
Solutions I've tried:
Updating all packages
Reinstalling react-tinder-cards
Read other questions related to this issue.
but still confused what the issue is
Code:
import React, { useState } from 'react'
import TinderCard from 'react-tinder-card'
import "./TinderCards.css"
function TinderCards() {
const [people, setPeople] = useState([
{
name: "Elon Musk",
url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Elon_Musk_Royal_Society_%28crop1%29.jpg/220px-Elon_Musk_Royal_Society_%28crop1%29.jpg'
},
{
name: "Jeff Bezos",
url: 'https://en.wikipedia.org/wiki/File:Jeff_Bezos_at_Amazon_Spheres_Grand_Opening_in_Seattle_-_2018_(39074799225)_(cropped).jpg'
},
])
const swiped = (direction, nameToDelete) => {
console.log("removing: " + nameToDelete)
// setLastDirection(direction)
}
const outOfFrame = (name) => {
console.log(name + "left the screen!")
}
return (
<div className="tinderCards">
<div className="tinderCards__cardContainer">
{people.map((person) => (
< TinderCard
className="swipe"
key={person.name}
preventSwipe={["up", "down"]}
onswipe={(dir) => swiped(dir, person.name)}
onCardLeftScreen={() => outOfFrame(person.name)}
></TinderCard>
))}
</div>
</div>
)
}
export default TinderCards
Error:

React hook error when changing size of rendered array

I get the following error: React Error: "Rendered more hooks than during the previous render", and it is because inside a mapped array that I render are buttons that have their own useState hooks.
So I have an array of projects that I render from a list. Initially, only 3 projects are shown, and clicking a button will load the whole list.
The problem is that inside project can be multiple ProjectButtons, and those ProjectButtons are components because I want to use special hover states using the useState hook.
But when I change the size of the project list being rendered, it throws an error because of the useState hook inside the ProjectButton component.
import { projects } from "../lib/projectList";
const Projects: FC = () => {
// Initially use a portion of the array
const [projectArray, setProjectArray] = useState(projects.slice(0, 3));
// Load the whole array on button click
const loadMoreProjects = () => {
setProjectArray([...projects]);
}
const ProjectButton = (button: { type: string, link: string }) => {
// Removing this useState hook fixes the problem, but I need it for my design
const [hoverColor, setHoverColor] = useState("#0327d8");
const handleMouseEnter = () => {
setHoverColor("white");
}
const handleMouseLeave = () => {
setHoverColor(original);
}
return (
<a href={button.link} rel="noreferrer" target="_blank" key={button.link}>
<button onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<WebsiteIcon className="projectButtonIcon" fill={hoverColor} />
<p>{button.type}</p>
</button>
</a>
);
}
return projectArray.map(project => (
...
<div className="projectLinks">
{project.buttons.map(button => ProjectButton(button))}
</div>
...
<Button onClick={loadMoreProjects}>Load More</Button>
));
}
You've defined ProjectButton within your Projects component, so you're breaking the rule of hooks - specifically "Only Call Hooks at the Top Level".
Move the ProjectButton component out of the scope of Projects and it will be happy.
This is happening because you are using hooks inside a function and it should be used directly inside a component.
This can solved if you create ProjectButton as a component instead of function.
Here is the updated code:
import { projects } from "../lib/projectList";
const ProjectButton = (button) => {
// Removing this useState hook fixes the problem, but I need it for my design
const [hoverColor, setHoverColor] = useState("#0327d8");
const handleMouseEnter = () => {
setHoverColor("white");
};
const handleMouseLeave = () => {
setHoverColor(original);
};
return (
<a href={button.link} rel="noreferrer" target="_blank" key={button.link}>
<button onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<WebsiteIcon className="projectButtonIcon" fill={hoverColor} />
<p>{button.type}</p>
</button>
</a>
);
};
const Projects: FC = () => {
// Initially use a portion of the array
const [projectArray, setProjectArray] = useState(projects.slice(0, 3));
// Load the whole array on button click
const loadMoreProjects = () => {
setProjectArray([...projects]);
}
return projectArray.map(project => (
...
<div className="projectLinks">
{project.buttons.map((button) => (
<ProjectButton {...button} />
))}
</div>
...
<Button onClick={loadMoreProjects}>Load More</Button>
));
}

Images from array in an object not displaying using React.js

I am having problems rendering images from array in carousel. Here is what I am doing
This is my object that has the array I want to map
export const data = [
{
id: 1,
name: "Some name ",
desc: "Some desc",
img: ("../../images/secondary/placeholder.jpg"),
},]
export const projectsData = {
1: {
title: "Some title 2",
subtitle: 'Some subtitle 2',
description: 'Lorem 2 ',
images: [
("../../images/photos2/2osnova1.png"),
("../../images/photos2/2osnova2.png"),
("../../images/photos2/2osnova3.png"),
("../../images/photos2/2presek1.png"),
("../../images/photos2/2presek2.png"),
("../../images/photos2/2pogled1.png"),
("../../images/photos2/2pogled2.png"),
("../../images/photos2/2pogled3.png")
]
}
}
here is the component
import React, { Component } from "react";
import Carousel from "react-bootstrap/Carousel";
import ControlledCarousel from "./ControlledCarousel";
import { useParams } from "react-router-dom";
import { projectsData } from "./dataapp";
export default function Appartments() {
let { id } = useParams();
let curProject = projectsData[id];
return (
<div>
<div className="left-wrapper">
<h1>{curProject.title}</h1>
<h2>{curProject.subtitle}</h2>
<p>{curProject.description}</p>
</div>
<div className="right-wrapper">
<ControlledCarousel images={curProject.images} />
</div>
</div>
);
}
and here is the carousel I want to display them in
import React, { Component, useState } from "react";
import Carousel from "react-bootstrap/Carousel";
function ControlledCarousel(images) {
const [index, setIndex] = useState(0);
console.log(images.images);
const handleSelect = (selectedIndex, e) => {
setIndex(selectedIndex);
};
return (
<div>
{images.images.map((projectsDataApp, index) => {
return (
<div>
<Carousel activeIndex={index} onSelect={handleSelect} indicators={false}>
<Carousel.Item interval={1000000} >
<img src={`${projectsDataApp.images}`} alt="" className="imgdummy" />
</Carousel.Item>
</Carousel>
</div>
);
})}
</div>
);
}
I tried placing the images both in src and public, also tried importing them from Imgur and Google Images, but nothing works. And there is no error message and when I console.log the images, it shows the array.
so there is many problems it seems like :
you are putting a list inside the src attribute which is wrong
additionally it seems like you are trying to access images the aren't stored in the 'public' directory which isn't visible to the browser... in case of storing images in the 'src' dir you should import them first and use the values imported as the src file...
to post an image in a file you should import it, or access a file that exist in the public directory :
for example :
import imgSrc from '../../images/photos2/2osnova1.png"'
function Image(){
return <img src={imgSrc}/>
}
for your case (if you did put it in public) :
try to render many components for each img src:
instead of:
<Carousel.Item interval={1000000} >
<img src={`${projectsDataApp.images}`} alt="" className="imgdummy" />
</Carousel.Item>
do:
{projectsDataApp.images.map(imageSrc=><Carousel.Item interval={1000000} >
<img src={`${imageSrc}`} alt="" className="imgdummy" />
</Carousel.Item>)}
There are a couple of errors with your code. First, the way you're handling props and there are images of images everywhere. I cleaned it up a bit and renamed a few variables to make more sense. Your img's src were undefined that's why you couldn't display the images.
I checked the code with images from unsplash. The code below works fine. If you want to host the images from the public folder, make sure the path is correct. If there is an images folder inside the public folder, your path will look like this: /images/something.jpg.
You also don't want to have two variables named index accessible from the same scope. I also changed them.
Another error was how you wanted to include the images inside the Carousel. You should have one Carousel component, and many Carousel.Item components with the images inside. So you need to map over the images array inside the Carousel component. Also, in React, if you iterate over an array, you need to add a key prop. In this case it's <Carousel.Item key={i} ....
const projectsData = {
1: {
title: "Some title 2",
subtitle: "Some subtitle 2",
description: "Lorem 2 ",
images: [
"https://source.unsplash.com/WLUHO9A_xik/800x450",
"https://source.unsplash.com/PLsEI2ZOrGA/800x450",
"https://source.unsplash.com/L8o2sIPSOnc/800x450",
"https://source.unsplash.com/6Pg2ms04ouM/800x450",
"https://source.unsplash.com/7ZWVnVSaafY/800x450",
"https://source.unsplash.com/O6RPWul11XI/800x450",
"https://source.unsplash.com/LcnNWTCkzUU/800x450"
]
}
};
function ControlledCarousel({ images }) {
const [index, setIndex] = useState(0);
const handleSelect = (selectedIndex, e) => {
setIndex(selectedIndex);
};
return (
<Carousel activeIndex={index} onSelect={handleSelect} indicators={false}>
{images.map((image, i) => (
<Carousel.Item key={i} interval={1000}>
<img src={image} alt="" className="imgdummy" />
</Carousel.Item>
))}
</Carousel>
);
}
function App() {
let { id } = useParams();
let curProject = projectsData[id];
return (
<div>
<div className="left-wrapper">
<h1>{curProject.title}</h1>
<h2>{curProject.subtitle}</h2>
<p>{curProject.description}</p>
</div>
<div className="right-wrapper">
<ControlledCarousel images={curProject.images} />
</div>
</div>
);
}
There's a simple way to do this.
const Images = [
{
id: 0,
image: require("../../Assets/Images/Icons/atom.png").default,
},
];
export default Images;
Replace your own image/icon at location from src folder ✌
I found the problem in my array it should be like this
1: {
title: "Some title 2",
subtitle: 'Some subtitle 2',
description: 'Lorem 2 ',
images: [
{
image: "../../images/photos2/2osnova1.png"
},
{
image: "../../images/photos2/2osnova1.png"
}, {
image: "../../images/photos2/2osnova1.png"
},
]
}
}
instead of my previous
export const projectsData = {
1: {
title: "Some title 2",
subtitle: 'Some subtitle 2',
description: 'Lorem 2 ',
images: [
("../../images/photos2/2osnova1.png"),
("../../images/photos2/2osnova2.png"),
("../../images/photos2/2osnova3.png"),
("../../images/photos2/2presek1.png"),
("../../images/photos2/2presek2.png"),
("../../images/photos2/2pogled1.png"),
("../../images/photos2/2pogled2.png"),
("../../images/photos2/2pogled3.png")
]
}
}

Resources