How to solve problem with 2items with the same key? - reactjs

I usually using uuid from react-uuid but this time I get all time an error even I try to combine it with unique item.id..
<Swiper
{...params}
>
{listMovie?.map((item, index) =>{
const time = new Date(item.release_date)
return(
<React.Fragment key={`${item.id + uuid()}`}>
<SwiperSlide >
<Grid item className="items">
<Card sx={{ maxWidth: "350" }}>
<div className="favorite">
<IconContext.Provider
value={{ color: 'red', size: '30px' }}
>
<div className="fav" onClick={() => FavHanlder(item, index)}>
{likes.includes(item.id) ? <MdFavorite/> : <MdFavoriteBorder/>}
</div>
</IconContext.Provider> </div>
<Link to={`/movie/${item.id}`}>
<CardMedia
component="img"
height="350"
image={`${apiConfig.w500Image(item.poster_path)}`}
// alt={item.Title}
/>
<CardContent>
</CardContent>
</Link>
</Card>
<div className="title">
<Typography variant="body2" color="white" >
{item.original_title}
</Typography>
<Typography variant="body2" color="white" >
({time?.getFullYear()})
</Typography>
<div style={{display: "flex", float: "left", paddingLeft: "10px", paddingRight: "10px"}}>
<ReactStars
count={10}
value={item.vote_average}
size={10}
isHalf={true}
emptyIcon={<i className="far fa-star"></i>}
halfIcon={<i className="fa fa-star-half-alt"></i>}
fullIcon={<i className="fa fa-star"></i>}
activeColor="#ffd700"
/><p style={{fontSize: "5px"}}>/{item.vote_count}votes</p></div>
</div>
</Grid>
</SwiperSlide>
</React.Fragment>
)})}
</Swiper>
I am a little bit confused, because this is an error of beginners.
full msg:
Warning: Encountered two children with the same key, .0. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

Related

Search Input with side button on Tailwind CSS

So i try to display and search bar with button on the right side of it but i keep geeting this view even though i have display it as flex and justify center, and even when i change it into row it still show up as image below
here is my code:
return (
<div className="p-2">
<div className="text-left pl-4 pb-4 font-bold text-3xl">
<h2>Detail SKU</h2>
</div>
<div className="p-2 justify-center mt-4 flex">
<form
onSubmit={(e) => {
e.preventDefault();
}}
>
<Autocomplete
style={{ width: "100%" }}
id="grouped-demo"
options={options.sort(
(a, b, index) => -b.firstLetter.localeCompare(a.firstLetter)
)}
groupBy={(option) => option.firstLetter}
getOptionLabel={(option) => option.title}
sx={{ width: 300 }}
renderInput={(params) => {
params.inputProps.onKeyDown = handleKeyDown;
return <TextField {...params} label="Search SKU" />;
}}
renderGroup={(params) => (
<li key={params.key}>
<GroupHeader>{params.group}</GroupHeader>
<GroupItems>{params.children}</GroupItems>
</li>
)}
/>
<Button variant="contained">Search</Button>
</form>
</div>
<Box sx={{ width: "100%", typography: "body1" }}>
<TabContext value={value} index={0} classes={{ root: useStyles.tab }}>
<Box sx={{ borderColor: "divider", p: 0 }}>
<TabList
index={0}
classes={{ root: useStyles.tab }}
onChange={handleChange}
variant="scrollable"
scrollButtons="auto"
aria-label="scrollable auto tabs example"
>
<Tab label="BOM" value="1" />
<Tab label="Routing" value="2" />
<Tab label="Depre" value="3" />
<Tab label="OMC" value="4" />
</TabList>
</Box>
<TabPanel style={{ padding: 10 }} value="1">
<div className="m-0 p-0" style={{ height: 400, width: "100%" }}>
<DataGrid {...data} components={{ Toolbar: GridToolbar }} />
</div>
</TabPanel>
<TabPanel value="2">Routing</TabPanel>
<TabPanel value="3">Depre</TabPanel>
<TabPanel value="4">OMC</TabPanel>
</TabContext>
</Box>
</div>
);
};
any help on it??, i've been figure it out but it seems dont help at all or where did do wrong here actually??
try removing display classname flex
<div className="p-2 justify-center mt-4">

When I click the Recipe button both recipes show at one time and not individually

I am trying to show 2 different recipes depending on what recipe button I am clicking and unsure how to get that to stop and only show individual recipes.
\\First Card
<Card style={{ width: '18rem' }} className="Chicken">
<Card.Img variant="top" src={chicken} className="Fav_image" />
<Card.Body>
<Card.Title className="Fav_title">Chicken Paprakash</Card.Title>
<Card.Text className="Fav_text">
This is one of my favourite fall/winter recipes to make.
</Card.Text>
<Button variant="outlined" onClick={handleOpen} className="button">Recipe</Button>
</Card.Body> <Card>
\\Second Card
<Card style={{ width: '18rem' }} className="Fajita">
<Card.Img variant="top" src={fajita} className="Fav_image" />
<Card.Body>
<Card.Title className="Fav_title">Chicken Fajitas</Card.Title>
<Card.Text className="Fav_text">
Great for when you only have a few minutes to cook dinner.
</Card.Text>
<Button variant="outlined" onClick={handleOpen} className="button">Recipe</Button>
</Card.Body> <Card>
Here is the issue:
I tried multiple different fixes on Stack overflow but not luck
I assume that you're using the same useState for onClick={handleOpen} in your button? They're both opening due to the shared useState. The best way to solve this is to make another component where you render the <Card/>. This way each card component regulates its own state.
First step will be to create a state to store current opened food item:
const [currentOpen, setCurrentOpen] = React.useState(false);
Also change item handle open and handle close
const handleOpen = (item) => {
setOpen(true);
setCurrentOpen(item);
};
const handleClose = (item) => {
setOpen(false);
setCurrentOpen(item);
};
Now simply check for current item open while returning a card:
{currentOpen === "chicken1" && ()
{currentOpen === "chicken2" && ()
Here is whole code (components/Favourites/index.jsx):
import React from "react";
import Card from "react-bootstrap/Card";
import board from "../../assets/Favourites/0.jpg";
import chicken from "../../assets/Favourites/1.jpg";
import fajita from "../../assets/Favourites/2.jpg";
import Backdrop from "#mui/material/Backdrop";
import Box from "#mui/material/Box";
import Modal from "#mui/material/Modal";
import Fade from "#mui/material/Fade";
import Button from "react-bootstrap/Button";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import Typography from "#mui/material/Typography";
// import Nav from 'react-bootstrap/Nav';
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
border: "2px solid #000",
boxShadow: 24,
p: 4,
};
function Favourite() {
const [open, setOpen] = React.useState(false);
const [currentOpen, setCurrentOpen] = React.useState(false);
const handleOpen = (item) => {
setOpen(true);
setCurrentOpen(item);
};
const handleClose = (item) => {
setOpen(false);
setCurrentOpen(item);
};
return (
<>
<img
className="head-img"
src={board}
style={{ width: "100vw", height: "100vh" }}
alt="cutting board"
/>
<h1 className="Haleys_Favourites">Haley's Favourite Recipes</h1>
<Card style={{ width: "18rem" }} className="Chicken">
<Card.Img variant="top" src={chicken} className="Fav_image" />
<Card.Body>
<Card.Title className="Fav_title">Chicken Paprakash</Card.Title>
<Card.Text className="Fav_text">
This is one of my favourite fall/winter recipes to make.
</Card.Text>
<div>
<Button
variant="outlined"
onClick={() => handleOpen("chicken1")}
className="button"
>
Recipe
</Button>
{currentOpen === "chicken1" && (
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={open}
onClose={() => handleClose("chicken1")}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<Box sx={style}>
<Typography
id="transition-modal-title"
variant="h6"
component="h2"
className="chicken_title"
>
Chicken Paprakash
</Typography>
<Typography
id="transition-modal-title"
variant="subtitle1"
component="h2"
className="chicken_serving"
>
Serving: 4 people
</Typography>
<Row xs={1} md={2}>
<Col>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
>
Ingredients:
<ol>
<li>4 chicken legs</li>
<li>oil</li>
<li>half an onion (chopped) </li>
<li>4 tablespoons of paprika</li>
<li>2 1/2 cups chicken broth</li>
<li>1 tub of sour cream</li>
<li>1 tablespoon of flour</li>
<li>salt</li>
<li>egg noodles</li>
</ol>
</Typography>
</Col>
<Col>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
>
Instructions:
<ol>
<li>
Season chicken with salt and pepper then brown
chicken in oil.
</li>
<li>
As chicken is browning, combine sour cream and
flour.
</li>
<li>Put browned chicken in dutch oven.</li>
<li>Add more oil and cook onions until soft.</li>
<li>
Add paprika and stir completely. Add sour cream
and onion mix and stir completley and then add
chicken broth
</li>
<li>
Stir until all combined and cook for 10 minutes.
</li>
<li>
Pour sauce into dutch oven and cook at 350% for 45
minutes
</li>
<li>Serve with buttery egg noodles</li>
</ol>
</Typography>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
className="exit"
variant="subtitle1"
>
Click outside of the box to exit!
</Typography>
</Col>
</Row>
</Box>
</Fade>
</Modal>
)}
</div>
</Card.Body>
</Card>
<Card style={{ width: "18rem" }} className="Fajita">
<Card.Img variant="top" src={fajita} className="Fav_image" />
<Card.Body>
<Card.Title className="Fav_title">Chicken Fajitas</Card.Title>
<Card.Text className="Fav_text">
Great for when you only have a few minutes to cook dinner.
</Card.Text>
<div>
<Button
variant="outlined"
onClick={() => handleOpen("chicken2")}
className="button"
>
Recipe
</Button>
{currentOpen === "chicken2" && (
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={open}
onClose={() => handleClose("chicken2")}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<Box sx={style}>
<Typography
id="transition-modal-title"
variant="h6"
component="h2"
className="Fav_title"
>
Chicken Fajitas
</Typography>
<Typography
id="transition-modal-titles"
variant="subtitle1"
component="h2"
className="Fav_serving"
>
Serving: 4 people
</Typography>
<Row>
<Col md={6}>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
>
Ingredients:
<ol>
<li>3 chicken breast</li>
<li>oil</li>
<li>half an onion (sliced)</li>
<li>2 large peppers (sliced)</li>
<li>1-2 Old El Paso Fajita seasoning packets</li>
<li>Tortillas</li>
</ol>
</Typography>
</Col>
<Col md={6}>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
>
Instructions:
<ol>
<li>Cook chicken in oil until cooked.</li>
<li>Add packets of seasoning.</li>
<li>Add onion and peppers.</li>
<li>
1/4-2/3 cups (depending how many packets used).
</li>
<li>Cook everything for 3-5 minutes</li>
<li>
Put in tortilla with all condaments you want.
</li>
</ol>
</Typography>
<Typography
id="transition-modal-description"
sx={{ mt: 2 }}
className="exit"
variant="subtitle1"
>
Click outside of the box to exit!
</Typography>
</Col>
</Row>
</Box>
</Fade>
</Modal>
)}
</div>
</Card.Body>
</Card>
{/* <Nav className="Fav_Home">
<Nav.Item>
<Nav.Link className="nav_home" href="/Home">Home</Nav.Link>
</Nav.Item>
</Nav> */}
</>
);
}
export default Favourite;

react-infinite-scroll not working inside Material UI Drawer

I am currently using react-infinite-scroll-component to paginate the comments from a certain post. There is a button in the comment section which shows a drawer that is supposed to show the paginated comments. The problem is, the react-infinite-scroll-component doesn't work, as it does not fire
the "next" function.
Here is the code:
<div>
<Drawer
anchor={"bottom"}
open={open}
onClose={handleDrawer}
style={{ height: "100vh", overflow: "auto", margin: "0px 4px" }}
>
<Toolbar>
<Typography variant="h4" style={{ flexGrow: 1 }}>
Comments
</Typography>
<IconButton onClick={handleDrawer}>
<CloseIcon />
</IconButton>
</Toolbar>
<Divider />
<br />
<CommentForm
comment={comment}
handleChange={handleChange}
handleSubmit={handleSubmit}
/>
<InfiniteScroll
dataLength={page}
next={More}
hasMore={hasMore}
loader={
<>
<br />
<CircularProgress />
</>
}
style={{
overflow: "hidden",
}}
scrollThreshold={1}
>
<CommentList comments={comments} id={session.id} />
</InfiniteScroll>
</Drawer>
</div>
The drawer is mostly similar to Youtube's comment drawer on the mobile app. Is there anything I am missing here?
Probably, the problem is the relation with Drawer and Infinite Scroll height. The height of Infinite Scroll is not reaching the right point to trigger next function. If you provide the demo in Codesandbox would be easier to understand.
Fixed height of infinite scroll container
<Box sx={{ height: 500 }}>
<InfiniteScroll
dataLength={page}
next={More}
hasMore={hasMore}
loader={
<>
<br />
<CircularProgress />
</>
}
style={{
overflow: "hidden",
}}
scrollThreshold={1}
>
<CommentList comments={comments} id={session.id} />
</InfiniteScroll>
</Box>

Accordion - Open first tab from a mapped array - React TS

{accordion.map(accordionItem => (
<AccordionItem
key={accordionItem.title}
text={accordionItem.text}
title={accordionItem.title}
></AccordionItem>
))}
I have an Accordion component that maps over an array of data. I am trying to open just the first tab. There are properties you can add to default expand all or none, but wondering how to do this on the first tab?
Material UI also has customised Accordions but they are focused when all data is in one file and not mapped through an array.
<Accordion className={classes.accordion} defaultExpanded={false}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls='panel1a-content'
id='panel1a-header'
style={{
borderBottom: '2px solid #EBEDF7'
}}
>
<Typography className={classes.heading}>{title}</Typography>
</AccordionSummary>
<AccordionDetails>
<Text label={text} className={classes.body} html>
{text}
</Text>
</AccordionDetails>
</Accordion>
This seem to work for me with MUI v5 to open first item (summary) of the accordion
...
summaries.map((summary, index) => (
<MuiAccordion
defaultExpanded={index === 0 ? true : false}
key={summary.id}
>
...
In my case I know what the title of the tabs will be so I was able to do a simple if statement that would open the first tab if the tabs name was as such.
const firstTabCheck =
title === 'Invest some of it' ? (
<Accordion className={classes.accordion} defaultExpanded={true}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls='panel1a-content'
id='panel1a-header'
style={{
borderBottom: '2px solid #EBEDF7'
}}
>
<Typography className={classes.heading}>{title}</Typography>
</AccordionSummary>
<AccordionDetails>
<Text label={text} className={classes.body} html>
{text}
</Text>
</AccordionDetails>
</Accordion>
) : (
<Accordion className={classes.accordion} defaultExpanded={false}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls='panel1a-content'
id='panel1a-header'
style={{
borderBottom: '2px solid #EBEDF7'
}}
>
<Typography className={classes.heading}>{title}</Typography>
</AccordionSummary>
<AccordionDetails>
<Text label={text} className={classes.body} html>
{text}
</Text>
</AccordionDetails>
</Accordion>
)
return firstTabCheck
I'm sure there is a cleaner way to do this if anyone wants to reply but this has fixed my issue for the time being.
{forms.map((form,index) => {
return (
<Accordion expanded={expanded === `panel_${index}`} onChange={handleChange(`panel_${index}`)}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1bh-content"
id="panel1bh-header"
>
{form.status === "pending" && (
<Chip
style={{ margin: '0' }}
size="small"
label={form.status}
color="default"
clickable
icon={<HistoryIcon />}
/>
)}
{form.status === "approved" && (
<Chip
style={{ margin: '0' }}
size="small"
label={form.status}
color="primary"
clickable
icon={<DoneIcon />}
/>
)}
{form.status === "rejected" && (
<Chip
style={{ margin: '0' }}
size="small"
label={form.status}
color="secondary"
clickable
icon={<ClearIcon />}
/>
)}
<Typography className={classes.heading}>{form.typeOfleave}</Typography>
<Typography className={classes.secondaryHeading}>{moment(form.createdAt).format('MMMM Do YYYY, h:mm:ss a')}</Typography>
</AccordionSummary>
<AccordionDetails style={{ display: 'flex', flexDirection: 'column' }}>
<div>
<Typography gutterBottom className={classes.secondaryHeading}>
Reason : {form.reason}
</Typography>
</div>
<div style={{ display: 'flex' }}>
<Typography className={classes.secondaryHeading}>
From : {moment(form.from).subtract(10, 'days').calendar()}
</Typography>
<Typography className={classes.secondaryHeading} style={{ marginLeft: '20px' }}>`enter code here`
To : {moment(form.to).subtract(10, 'days').calendar()}
</Typography>
</div>
</AccordionDetails>
</Accordion>
)
})}
set expanded state (default state) to '0' because array index is starting from 0
const [expanded, setExpanded] = React.useState('panel_0');
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};

Passing data to child component is not working in react

***Menucomponent.js***
I have a on which onClick handler is working and sending dish detail to getDish function.which is passing data as a props to Cart component.
But it not working .Dishdetail is showing in menu component when i console.log it but won't show on cart component and undefined error.
<div className="row">
{this.props.dishes.map((dish, index) => {
return (
<Card
className="col-xl-2 col-lg-2 col-md-4 col-sm-6 m-3 text-white"
style={{ height: "400px", backgroundColor: "#1A0301" }}
>
<CardBody>
<CardTitle>{this.props.dishes[index].name}</CardTitle>
<CardSubtitle></CardSubtitle>
</CardBody>
<img
height="30%"
src={this.props.dishes[index].image}
alt={this.props.dishes[index].description}
/>
<button className="bg-dark text-white mt-4 " width="100">
<CardText>
Serve for - {this.props.dishes[index].serving}
</CardText>
</button>
<CardBody>
<CardSubtitle>
$$$ -{this.props.dishes[index].price}
</CardSubtitle>
</CardBody>
<button
className="text-white m-2 p-2 "
style={{ backgroundColor: "#FDA50F" }}
onClick={() => this.getDish(this.props.dishes[index])}
>
Order Now
</button>
<button
className="text-white m-2 p-2 "
style={{ backgroundColor: "#FDA50F" }}
>
<Link to="/cart" className="text-white">
Check cart
</Link>
</button>
</Card>
function which handle onclick event
getDishId(dishdetail)
{
return (
<React.Fragment>
<div className="container-fluid">{console.log(dishdetail.name)}</div>
<Cart dishdetail={this.props.dishdetail} />
</React.Fragment>
);
}
CartComponent.js
const Cart = (props) => {
return (
<React.Fragment>
<Card>
<CardImg width="100%" src="/assests/images/buffet.png" />
<CardBody>
<CardTitle>{console.log(props.dishdetail)}</CardTitle>
<CardText>{props.description}</CardText>
<Button>Button</Button>
</CardBody>
</Card>
</React.Fragment>
);
};

Resources