After clicking on the FavoriteIcon inside the ExamplesCard all the icons turn red instead of just one icon. I'm using useState to change icon state value between true and false and style to change icon color.
Componenet ExamplesCard.tsx
import * as React from "react";
import {
Box,
Card,
CardActionArea,
CardActions,
CardContent,
CardMedia,
Grid,
Typography
} from "@mui/material";
import FavoriteIcon from "@mui/icons-material/Favorite";
import { ButtonProps } from "./ButtonProps";
import data from "./data/data.json";
import { useState } from "react";
export default function ExemplesCard() {
const [iconFavorite, setIconFavorite] = useState(false);
const ChangeColorFavorite = () => {
setIconFavorite(!iconFavorite);
};
return (
<Box sx={{ flexGrow: 1, margin: "0 2rem" }}>
<Grid
container
justifyContent="center"
spacing={{ xs: 8, sm: 8, md: 8, lg: 8, xl: 8 }}
className="GRID1"
>
{data.map((item) => {
return (
<Grid
item
xs={12}
sm={6}
md={4}
lg={3}
xl={2}
sx={{
display: "flex",
justifyContent: "center",
marginTop: "1rem"
}}
>
<Card
key={item.id}
sx={{
p: "1rem",
boxShadow: 4,
maxWidth: {
xs: "250px",
sm: "250px",
md: "280px",
lg: "300px",
xl: "300px"
}
}}
>
<CardActionArea>
<CardMedia component="img" height="140" image={item.img} />
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{item.title}
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with
over 6,000 species, ranging across all continents except
Antarctica
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<ButtonProps
size="small"
endIcon={
<FavoriteIcon
onClick={ChangeColorFavorite}
style={{ color: iconFavorite ? "red" : "white" }}
/>
}
>
Favorite
</ButtonProps>
</CardActions>
</Card>
</Grid>
);
})}
</Grid>
</Box>
);
}
I used the useState to store the current value of the icon (true or false), however, it was not enough to leave only the icon clicked in red. When clicking on the FavoriteIcon I expected that only the icon clicked would turn red.
CodePudding user response:
Try doing this instead. It might work.
import * as React from "react";
import {
Box,
Card,
CardActionArea,
CardActions,
CardContent,
CardMedia,
Grid,
Typography
} from "@mui/material";
import FavoriteIcon from "@mui/icons-material/Favorite";
import { ButtonProps } from "./ButtonProps";
import data from "./data/data.json";
import { useState } from "react";
export default function ExemplesCard() {
const [iconFavorite, setIconFavorite] = useState(false);
return (
<Box sx={{ flexGrow: 1, margin: "0 2rem" }}>
<Grid
container
justifyContent="center"
spacing={{ xs: 8, sm: 8, md: 8, lg: 8, xl: 8 }}
className="GRID1"
>
{data.map((item) => {
return (
<Grid
item
xs={12}
sm={6}
md={4}
lg={3}
xl={2}
sx={{
display: "flex",
justifyContent: "center",
marginTop: "1rem"
}}
>
<Card
key={item.id}
sx={{
p: "1rem",
boxShadow: 4,
maxWidth: {
xs: "250px",
sm: "250px",
md: "280px",
lg: "300px",
xl: "300px"
}
}}
>
<CardActionArea>
<CardMedia component="img" height="140" image={item.img} />
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{item.title}
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with
over 6,000 species, ranging across all continents except
Antarctica
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<ButtonProps
size="small"
endIcon={
<FavoriteIcon
onClick={() => setIconFavorite(true)}
style={iconFavorite ? {color: "red"} : {color: "black"}}
/>
}
>
Favorite
</ButtonProps>
</CardActions>
</Card>
</Grid>
);
})}
</Grid>
</Box>
);
}
CodePudding user response:
your are using one state iconFavorite
of type boolean where you actually want to use amount of the data array entries of type boolean[]. Every icon needs its own color state. This code works.
import * as React from "react";
import {
Box,
Card,
CardActionArea,
CardActions,
CardContent,
CardMedia,
Grid,
Typography
} from "@mui/material";
import FavoriteIcon from "@mui/icons-material/Favorite";
import { ButtonProps } from "./ButtonProps";
import data from "./data/data.json";
import { useState } from "react";
export default function ExemplesCard() {
const [iconFavorite, setIconFavorite] = useState([ ...Array(data.length).keys() ].map( i => false));
const ChangeColorFavorite = (idx: number) => {
const newIconFavorite = iconFavorite.slice();
newIconFavorite[idx] = !iconFavorite[idx];
setIconFavorite(newIconFavorite);
};
return (
<Box sx={{ flexGrow: 1, margin: "0 2rem" }}>
<Grid
container
justifyContent="center"
spacing={{ xs: 8, sm: 8, md: 8, lg: 8, xl: 8 }}
className="GRID1"
>
{data.map((item,idx) => {
return (
<Grid
item
xs={12}
sm={6}
md={4}
lg={3}
xl={2}
sx={{
display: "flex",
justifyContent: "center",
marginTop: "1rem"
}}
>
<Card
key={item.id}
sx={{
p: "1rem",
boxShadow: 4,
maxWidth: {
xs: "250px",
sm: "250px",
md: "280px",
lg: "300px",
xl: "300px"
}
}}
>
<CardActionArea>
<CardMedia component="img" height="140" image={item.img} />
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{item.title}
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with
over 6,000 species, ranging across all continents except
Antarctica
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<ButtonProps
size="small"
endIcon={
<FavoriteIcon
onClick={() => ChangeColorFavorite(idx)}
style={{ color: iconFavorite[idx] ? "red" : "white" }}
/>
}
>
Favorite
</ButtonProps>
</CardActions>
</Card>
</Grid>
);
})}
</Grid>
</Box>
);
}