I am rendering the products in a table but I want to display them as card. Every time I touch the code it stops working, I've tried mixing them together but nothing, any suggestions?
function Products(props) {
function Products(products) {
if (products === null) return;
return products.map((product) => (
<ListGroup.Item key={product.Id}>
<Link to={`/products/${product.name}`} key={product.id}> {product.name}
</Link>
</ListGroup.Item>
));
}
return (
<>
<h1>Products</h1>
<Stack direction="horizontal" gap={3}>
<ListGroup className="align-self-start w-75">
<ProductContext.Consumer>
{({ products }) => Products(products)}
</ProductContext.Consumer>
</ListGroup>
<Outlet />
</Stack>
</>
);
}
export default Products;
Related
I am trying to render the images in React.js as a card content but it does not show the image.
The code to display image:
const Template = ({ template }) => {
console.log(template.preview_image) // <- It displays the image path
return (
<Card className="my-3 p-3 rounded">
<Link to={`/template/${template._id}`}>
<Card.Img src={template.preview_image} variant="top" />
</Link>
<Card.Body>
<Link to={`/template/${template._id}`}>
<Card.Title as="div">
<strong>{template.name}</strong>
</Card.Title>
</Link>
</Card.Body>
</Card>
);
};
The template prop coming from the following code:
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : (
<Row>
{templates &&
templates.map((template) => (
<Col key={template._id} sm={12} md={6} lg={4} xl={3}>
<Template template={template} />
</Col>
))}
</Row>
)}
The useEffect function:
const templateList = useSelector((state) => state.templateList);
const { error, loading, templates } = templateList;
useEffect(() => {
dispatch(listTemplates());
}, [dispatch]);
The images are also saved at the server side in the uploads folder.
Am I missing something?
I wanted to know what I'm doing wrong, to extract the first category from the Wordpress api.
I have a list of posts, and I just need to show the category, no link or anything.
With the code below it is bringing me an empty value.
export default function Blog({ posts }) {
const { status } = useSession();
if (status === 'loading') return <Loading />;
const getCategories = async (id) => {
const response = await axios.get(`${process.env.API_CONTENT}/categories/${id}`);
const category = response.data;
return category;
};
return (
<BlogPosts>
<Container className="default">
{posts.map((post, i) => (
<Post key={i}>
<Row>
<Col className="post-image" md={6}>
<PostImage>
<Link href={`/blog/${post.id}`}>
<a title={post.title.rendered}>
<img className="image" src={post._embedded['wp:featuredmedia']['0'].source_url} />
</a>
</Link>
</PostImage>
</Col>
<Col className="post-container" md={6}>
<PostContent>
<Link href={`/blog/${post.id}`}>
<a title={post.title.rendered}>
<h2 className="title">{post.title.rendered}</h2>
</a>
</Link>
<PostDetails date={post.modified} category={getCategories(post.categories[0])} />
<div className="excerpt" dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
<Link href={`/blog/${post.id}`}>
<a className="link" title={post.title.rendered}>
LEIA MAIS +
</a>
</Link>
</PostContent>
</Col>
</Row>
</Post>
))}
</Container>
</BlogPosts>
);
}
I think i dont understand sth.
I put every where nano id keys but still get error.
react-jsx-dev-runtime.development.js:117 Warning: Each child in a list should have a unique "key" prop.
Check the render method of Users.
import React from "react";
import {useQuery} from "#apollo/client"
import { ListGroup, Container, Row, Col,Card } from "react-bootstrap";
import {GET_USERS} from "../Queries/Queries"
import { nanoid } from 'nanoid'
function Users() {
const { loading, error, data}= useQuery(GET_USERS)
if (loading) return <p>Loading...</p>
if (error) return <p>Error</p>
return (
<Container>
{
data && data.users.map(user=>{
return(
<>
<br/>
<Row key={nanoid()}>
<Card key={nanoid()} style={{ width: '6rem' }}>
<Card.Img key={nanoid()} variant="top" src={user.avatar} />
</Card>
<br />
<Col key={nanoid()}>
<ListGroup key={nanoid()}>
<ListGroup.Item key={nanoid()}>Id: {user.id} </ListGroup.Item>
<ListGroup.Item key={nanoid()}>Email: {user.email}</ListGroup.Item>
<ListGroup.Item key={nanoid()}>Username: {user.username}</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</>
)
})
}
</Container>
);
}
export default Users;
The error message is saying that each item it is mapping needs a key so you just need to add one key to the parent container like so
function Users() {
const { loading, error, data}= useQuery(GET_USERS)
if (loading) return <p>Loading...</p>
if (error) return <p>Error</p>
return (
<Container>
{
data && data.users.map((user, index)=>{
return(
<Row key={index}>
<Card style={{ width: '6rem' }}>
<Card.Img variant="top" src={user.avatar} />
</Card>
<br />
<Col>
<ListGroup>
<ListGroup.Item>Id: {user.id} </ListGroup.Item>
<ListGroup.Item>Email: {user.email}</ListGroup.Item>
<ListGroup.Item>Username: {user.username}</ListGroup.Item>
</ListGroup>
</Col>
</Row>
)
})
}
</Container>
);
}
Instead of adding a parent container to what you had already I just remove dthe JSX tags and the BR. You should add a className to that row to get the desired space instead of using BR.
When you map somthing in react, react track nodes with unique keys. e.g
[{id:1,value:'value 1'},{id:2,value:'value 2'}].map((item,index) =>
(<Row key={`row-${item.id}`}>all content goes here.</Row>))
This key={row-${item.id}} should be unique for every looped Item.
As the title says, React is throwing an error about children in a list having unique keys and I have no clue why. I am building a Twitch chat clone, and this is happening with my emote picker, where every emote available for your use is listed as a clickable icon. Every map function I use spits out components with keys. I even went through every single component and added a unique key whether it really needed it or not, and I am still getting the warning. Clicking the first few trace links leads to nothing useful.
I know my code might not be super clear, and I apologize for this, but any help would be appreciated.
Here is the return statement for the affected component:
return (
<Popover placement="top">
<PopoverTrigger>
<Button disabled={!loggedIn || !connected}>
{
<Box
as="img"
width={[12, 10, 10, 8]}
alt="Emote Picker"
// src="https://static-cdn.jtvnw.net/emoticons/v2/305954156/static/light/3.0" // PogChamp
src="https://static-cdn.jtvnw.net/emoticons/v2/307445021/static/light/3.0" // Orangie
title="Emote Picker"
/>
}
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<Flex height={400} overflow="auto" direction="column">
{showBTTVChannel && (
<>
<PopoverHeader>BTTV Channel Emotes</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{bttvEmotes !== null &&
// eslint-disable-next-line array-callback-return
Object.keys(bttvEmotes).map((key, index) => {
if (bttvEmotes[key]['category'] === 'bttv_channel') {
return (
<ChatEmote
key={index}
name={key}
src={
bttvEmotes[key][userOptions.emoteQuality + 'x']
}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
})}
</Flex>
</PopoverBody>
</>
)}
{showFFZChannel && (
<>
<PopoverHeader>FFZ Channel Emotes</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{bttvEmotes !== null &&
// eslint-disable-next-line array-callback-return
Object.keys(bttvEmotes).map((key, index) => {
if (bttvEmotes[key]['category'] === 'ffz_channel') {
return (
<ChatEmote
key={index}
name={key}
src={
bttvEmotes[key][userOptions.emoteQuality + 'x']
}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
})}
</Flex>
</PopoverBody>
</>
)}
{showBTTVShared && (
<>
<PopoverHeader>BTTV Shared Emotes</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{bttvEmotes !== null &&
// eslint-disable-next-line array-callback-return
Object.keys(bttvEmotes).map((key, index) => {
if (bttvEmotes[key]['category'] === 'bttv_shared') {
return (
<ChatEmote
key={index}
name={key}
src={
bttvEmotes[key][userOptions.emoteQuality + 'x']
}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
})}
</Flex>
</PopoverBody>
</>
)}
{showEmotes &&
// eslint-disable-next-line array-callback-return
Object.keys(emoteSets.current).map(key => {
if (key !== 'Twitch Global') {
return (
<>
<PopoverHeader>{key}</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{emoteSets.current !== null &&
Object.keys(emoteSets.current[key]['emotes']).map(
(key, index) => {
return (
<ChatEmote
key={index}
name={key}
src={
userEmotes[key][
userOptions.emoteQuality + 'x'
]
}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
)}
</Flex>
</PopoverBody>
</>
);
}
})}
<PopoverHeader>BTTV Global Emotes</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{bttvEmotes !== null &&
// eslint-disable-next-line array-callback-return
Object.keys(bttvEmotes).map((key, index) => {
if (bttvEmotes[key]['category'] === 'bttv_global') {
return (
<ChatEmote
key={index}
name={key}
src={bttvEmotes[key][userOptions.emoteQuality + 'x']}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
})}
</Flex>
</PopoverBody>
{showEmotes && (
<>
<PopoverHeader>Twitch Global</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{emoteSets.current !== null &&
Object.keys(
emoteSets.current['Twitch Global']['emotes']
).map((key, index) => {
return (
<ChatEmote
key={index}
name={key}
src={userEmotes[key][userOptions.emoteQuality + 'x']}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
})}
</Flex>
</PopoverBody>
</>
)}
</Flex>
</PopoverContent>
</Popover>
);
key must added to the parent wrapper component which you're returning
key is missing -->
{showEmotes &&
// eslint-disable-next-line array-callback-return
//map second argument return the index of current element
Object.keys(emoteSets.current).map((key,i) => {
if (key !== 'Twitch Global') {
return (
//missing key
<div key={i}>
<PopoverHeader>{key}</PopoverHeader>
<PopoverBody>
<Flex flexWrap="wrap">
{emoteSets.current !== null &&
Object.keys(emoteSets.current[key]['emotes']).map(
(key, index) => {
return (
<ChatEmote
key={index}
name={key}
src={
userEmotes[key][
userOptions.emoteQuality + 'x'
]
}
height={8}
margin={1.5}
onClick={() => onClickHandler(key)}
/>
);
}
)}
</Flex>
</PopoverBody>
</>
does this solve issue ?
I'm trying to align horizontal card using grid with react-bootstrap and map function
I'm using redux to bring the Data through the props so I create a JSON to traverse it with a function Map
this is a fraction of my code
render() {
//const { tablaCliente } = this.state
//const { isLoading } = this.state
const { entity } = this.props;
return (
<div>
<Header></Header>
<div className="col-xs-4">
<a className="btn btn-primary" href="/newclient">Nuevo Cliente</a>
</div>
<br />
<center>
<Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
</center>
<Container>
{entity && entity.getAllEntities && entity.getAllEntities.length > 0 && entity.getAllEntities.map((item, index) => {
return (
<CardGroup value={item}key={index}>
<Card style={{ width: '1rem' }} >
<Card.Img variant="top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16b0e6bd8ef%20text%20%7B%20fill%3A%23999%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16b0e6bd8ef%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23373940%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.203125%22%20y%3D%2296.3%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" />
<Card.Body>
<Card.Title> Cliente {item.name}</Card.Title>
<Card.Text>
{item.description}
</Card.Text>
</Card.Body>
<ListGroup className="list-group-flush">
<ListGroupItem>Estado:{''}{JSON.stringify(item.state)}</ListGroupItem>
<ListGroupItem>Creado por: {item.createby}</ListGroupItem>
</ListGroup>
<Card.Body>
<Card.Link href="/cliente">Card Link</Card.Link>
<Card.Link href="/cliente">Editar</Card.Link>
</Card.Body>
</Card>
</CardGroup>)
})}
</Container>
</div>
);
}
I dont use react-bootstrap but u can achieve it by doing
<Container>
<div class='row'>
{this.map(value => {
return (
<div class='col-md-6'>
<Card />
</div>
)
});}
</div>
</Container>
This should work
Wrap the map function in row and the returning jsx in col
And dont just write a whole logic in jsx use functions or components