I'm trying to efficiently make a key-value tour in an array in reactjs.
However, I do not know how to display the "key" array without creating another map function.
const equipos = [
{
key: [
'Real Madrid',
'Manchester United',
'Champions League',
'English Premier League',
'Bayern Munchen',
'Juventus',
'Arsenal',
],
images: [
'http://as00.epimg.net/img/comunes/fotos/fichas/equipos/large/1.png',
'https://4.bp.blogspot.com/_Z_YWTFNHUvw/TQDBKNXdwcI/AAAAAAAACI0/COhwIG2PkFA/s320/Manchester-United%255B1%255D.png',
'http://www.stickpng.com/assets/images/5842fe06a6515b1e0ad75b3b.png',
'https://i.pinimg.com/originals/f1/44/fc/f144fc61d0b0ed7716d740aa9deefb07.png',
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/FC_Bayern_M%C3%BCnchen_logo_%282017%29.svg/1200px-FC_Bayern_M%C3%BCnchen_logo_%282017%29.svg.png',
'http://as00.epimg.net/img/comunes/fotos/fichas/equipos/large/29.png',
'https://i.pinimg.com/originals/98/32/8b/98328b1d64c5f93ef5eceea7586430d1.png',
],
},
];
console.log(equipos.images)
const IconosSeccion = () => (
<div className="containerIconosSeccion">
<div className="parentIconos" />
{equipos.map(equipo => (
<div>
{equipo.images.map(image => (
<div className="backgroundIconoIndependiente">
<img alt="#" className="iconoIndependiente" src={image} />
<span className="textoIconoIndependiente">Real madrid</span>
</div>
))}
</div>
))}
</div>
);
I want to show it in the span of the classname textIconoIndependiente.
Thank you!
I'm not sure your data is well formatted.
I suggest you another format. In that way, It's possible to render your image and the name of the club with only one map.
const equipos = [
{name:'Real Madrid',image:'http://as00.epimg.net/img/comunes/fotos/fichas/equipos/large/1.png',},
{name:'Manchester United',image:'https://4.bp.blogspot.com/_Z_YWTFNHUvw/TQDBKNXdwcI/AAAAAAAACI0/COhwIG2PkFA/s320/Manchester-United%255B1%255D.png',},
{name:'Champions League',image:'http://www.stickpng.com/assets/images/5842fe06a6515b1e0ad75b3b.png',},
{name:'English Premier League',image:'https://i.pinimg.com/originals/f1/44/fc/f144fc61d0b0ed7716d740aa9deefb07.png',},
{name:'Bayern Munchen',image:'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/FC_Bayern_M%C3%BCnchen_logo_%282017%29.svg/1200px-FC_Bayern_M%C3%BCnchen_logo_%282017%29.svg.png',},
{name:'Juventus',image:'http://as00.epimg.net/img/comunes/fotos/fichas/equipos/large/29.png',},
{name:'Arsenal',image:'https://i.pinimg.com/originals/98/32/8b/98328b1d64c5f93ef5eceea7586430d1.png'}
];
const IconosSeccion = () => (
<div className="containerIconosSeccion">
<div className="parentIconos" />
{equipos.map(equipo => (
<div>
<div className="backgroundIconoIndependiente">
<img alt="#" className="iconoIndependiente" src={equipo.image} />
<span className="textoIconoIndependiente">{equipo.name}</span>
</div>
</div>
))}
</div>
);
The second argument passed to the map function is the index, which you could use to read the correct key.
const IconosSeccion = () => (
<div className="containerIconosSeccion">
<div className="parentIconos" />
{equipos.map(equipo => (
<div>
{equipo.images.map((image, index) => (
<div className="backgroundIconoIndependiente">
<img alt="#" className="iconoIndependiente" src={image} />
<span className="textoIconoIndependiente">{equipo.key[index]}</span>
</div>
))}
</div>
))}
</div>
);
Use the second parameter to map, index, to get the correct image and key.
const IconosSeccion = () => (
<div className="containerIconosSeccion">
<div className="parentIconos" />
{equipos.map((equipo, i) => (
<div>
<div className="backgroundIconoIndependiente">
<img alt="#" className="iconoIndependiente" src={ equipo.images[i] } />
<span className="textoIconoIndependiente">{ equipo.key[i] }</span>
</div>
</div>
)}
</div>
);
Related
This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 5 months ago.
I am using the id gotten from next router.query to render elements dynamically it works when i access the room from next/link but when i refresh the page it throws this error
here is my code (note: roomId here was gotten from const {roomId} = router.query):
return (
<>
<div className={styles.header}>
<div className={styles.title}>{rooms[roomId].name}</div>
<div className={styles.headerCon}>
<div className={styles.roomUsers}>
<AvatarGroup
max={3}
total={Object.keys(rooms[roomId].users).length}
>
{Object.keys(rooms[roomId].users).map((user) => (
<Avatar
key={user + Math.random()}
alt={users[user].name}
src={users[user].profile_pic}
/>
))}
</AvatarGroup>
</div>
<div className={styles.headerIcons}>
<div className={styles.react}>
<AddReactionOutlinedIcon />
</div>
<div className={styles.notif}>
<NotificationsNoneOutlinedIcon />
</div>
<div className={styles.more}>
<MoreHorizOutlined />
</div>
</div>
</div>
</div>
{user.name === rooms[roomId].createdBy.name ? (
<div className={styles.begin}>
{!roomActive ? (
<button onClick={handleStartSession}>Start</button>
) : (
<button onClick={handleEndSession}>End</button>
)}
</div>
) : (
""
)}
<div className={styles.participators}>
<div className={styles.pAvatars}>
<Avatar
alt={rooms[roomId].createdBy.name}
src={rooms[roomId].createdBy.profile_pic}
/>
<div className={styles.userName}>{rooms[roomId].createdBy.name}</div>
<div className={styles.userRole}>Admin</div>
<div>
<audio autoPlay ref={userAudio} />
{peers.map((peer, index) => {
return <Audio key={index} peer={peer} />;
})}
</div>
</div>
{Object.keys(rooms[roomId].users)
.filter((user) => users[user].name !== rooms[roomId].createdBy.name)
.map((user) => (
<div className={styles.pAvatars} key={Math.random() + user}>
<Avatar alt={users[user].name} src={users[user].profile_pic} />
<div className={styles.userName}>{users[user].name}</div>
<div className={styles.userRole}>Admin</div>
</div>
))}
</div>
</>
);
}
As you can see much of what i am rendering on this page depends on that id, so can someone please help?
You try to access the query parameter before its state is ready. There is a workaround to solve this problem.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (router.isReady) {
// Do your stuff
// for example: assign query param to a state
}
}, [router.isReady]);
when i add product in cart there is nothing displayed in car and "items not found" error is displayed on the screen and when i try to use null check and npm start then error is not shown but still balnk page is displayed.
import React from 'react';
import Header from './Front/Header/Header';
const Cart = ({ cartitems ,handleAddProduct,handleRemoveProduct} ) => {
return (
<>
<Header />
<div className="cart-items">
<div className="cart-items-header"> cartitems</div>
{!cartitems?.length ? (
<div className="cart-items-empty"> No items added in cart</div>
) : null}
<div>
{cartitems?.length ? cartitems.map((item,name ,price ,image ,id) => (
<img
key={item.id}
className="cart-items-image"
src={item.image}
alt={item.name}
/>
)) : null}
</div>
<div>
<h3 className='cart-items-name'>
{item.name}</h3>
</div>
<div className='cart-items-function'>
<button className='cart-items-add' onClick={() =>handleAddProduct(item)}>
+
</button>
<button
className='cart-items-remove' onClick={()=>handleRemoveProduct(item)}>
-
</button>
</div>
<div
className='cart-items-price'>
{item.quantity}* ${item.price}
</div>
</div>
</>
);
}
export default Cart;
I think there are 2 problems in your code :
Firstly, I suppose that each item in your cartitems has the following structure :
item = {
id: 1,
name: "my item",
price: 2,
image: "http://mybeautifulurl.org/image.png"
}
If that is the case, you should pass item as the only argument in the map function, and access each props with item.id, item.name, item.price and item.image.
Some of your code is not in the map function but needs the item, so it cannot display anything.
Here is your updated code :
import React from "react";
import Header from "./Front/Header/Header";
const Cart = ({ cartitems, handleAddProduct, handleRemoveProduct }) => {
return (
<>
<Header />
<div className="cart-items">
<div className="cart-items-header"> cartitems</div>
{!cartitems?.length ? (
<div className="cart-items-empty"> No items added in cart</div>
) : null}
<div>
{cartitems?.length
? cartitems.map((item) => (
<>
<img
key={item.id}
className="cart-items-image"
src={item.image}
alt={item.name}
/>
<div>
<h3 className="cart-items-name">{item.name}</h3>
</div>
<div className="cart-items-function">
<button
className="cart-items-add"
onClick={() => handleAddProduct(item)}
>
+
</button>
<button
className="cart-items-remove"
onClick={() => handleRemoveProduct(item)}
>
-
</button>
</div>
<div className="cart-items-price">
{item.quantity}* ${item.price}
</div>
</>
))
: null}
</div>
</div>
</>
);
};
export default Cart;
Let me know if this solves the problem :)
Trying to loop inside a loop and getting error: value.forEach is not a function.
Dont know how to write this code inside a render
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{value.forEach(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}
Below should work provided value is populated as an array in later stages.
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{(value.forecast || []).map(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}
My component is being rendered in a single column equal to the photo I attached, but it is wrong, it was to be a 5x4 array.
edi1: In an old version of the code I did not have this problem, however I received some props, and since I have to constantly change the contents of the Component, I thought it was good to use state.
render() {
return (
<div className="App">
<Navbar onChange={this.onChange.bind(this)} />
<div className="container mt-10">
<div className="row">
{<RecipeItem list={this.state.searchString} />}
</div>
</div>
</div>
);
}
}
File RecipeItem.js
const RecipeList = ({ searchString }) => {
return(
<div>
<img className="card-img-top img-fluid" src={searchString.thumbnail} alt={searchString.title} />
<div className="card-body">
<h5 className="card-title">{searchString.title}</h5>
<p className="card-text">
<strong>Ingredients: </strong>{searchString.ingredients}
</p>
</div>
</div>
)
}
const RecipeItem = (props) => {
return (
<div className="col-sm-3 mt-4">
<div className="card">
{props.list && props.list.map((searchString, index) =>
<RecipeList searchString={searchString} key={index} />
)}
</div>
</div>
)
}
You're applying col-sm-3 before iterating on each element, you should apply the class on each iteration like this :
const RecipeItem = (props) => {
return (
props.list && props.list.map((searchString, index) =>
<div className="card col-sm-3 mt-4">
<RecipeList searchString={searchString} key={index} />
</div>
)
)
}
I'm mapping all of my files
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} />;
})
: null;
and then I'm trying to display it ProjectItemUser
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
</div>
</div>
</div>
);
}
}
This basically displays all the files, and each file is its own separate row. I would like to assign value to div element on each iteration, so I can control which file has been clicked.
I can access my id with: this.props._id
Should this be done using refs and if so, how ?
You should pass onClick function as parameter
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} onClick={() => { console.warn(item) } />;
})
: null;
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
<Button onClick={this.props.onClick} label="Click on me" />
</div>
</div>
</div>
);
}
}