I have an array which is consisted with some data. My Array is,
const faqData = [
{
q: "How Can We Help You?",
a: "Below are answers to our most commonly asked questions. If you cannot find an answer here, please contact us.",
},
{
q: "How Can We Help You?",
a: "Below are answers to our most commonly asked questions. If you cannot find an answer here, please contact us.",
},
{
q: "How Can We Help You?",
a: "Below are answers to our most commonly asked questions. If you cannot find an answer here, please contact us.",
},
];
For showing all of the data of the array inside cards, i am using map function which is,
{faqData.map((item, index) => {
return (
<SimpleFlexContainer
sx={{ flexDirection: "column", m: "20px 0px" }}
>
<SimpleFlexContainer
sx={{
background: "#F4F4F5",
width: "100%",
p: "15px 25px",
justifyContent: "space-between",
alignItems: "center",
}}
>
<SimpleFlexContainer>
<SmallTypo
sx={{ fontWeight: "bold", mr: { xs: "15px", md: "25px" } }}
>
Question
</SmallTypo>
<SmallTypo sx={{ fontWeight: "bold" }}>{item.q}</SmallTypo>
</SimpleFlexContainer>
<Box>
<IconButton>
{openDes ? (
<RemoveIcon onClick={() => setDes(false)} />
) : (
<AddIcon onClick={() => setDes(true)} />
)}
</IconButton>
</Box>
</SimpleFlexContainer>
<Box
sx={{
display: openDes ? "inherit" : "none",
background: "white",
p: "26px",
border: "1px solid #F4F4F5",
}}
>
<SmallTypo>{item.a}</SmallTypo>
</Box>
</SimpleFlexContainer>
);
})}
When users click on the individual cards, i want to show a border color around that specific card. How to achieve this?
CodePudding user response:
The best solution for this is to create a separate component. Something like this:
import { useState } from 'React';
const FAQComponent = (props) => {
const {
item,
} = props;
const [active, setActive] = useState(false);
const [openDes, setDes] = useState(false);
return (
<SimpleFlexContainer
sx={{ flexDirection: "column", m: "20px 0px" }}
onClick={() => setActive(pre => !pre)}
>
<SimpleFlexContainer
sx={{
background: "#F4F4F5",
width: "100%",
p: "15px 25px",
justifyContent: "space-between",
alignItems: "center",
}}
>
<SimpleFlexContainer>
<SmallTypo
sx={{ fontWeight: "bold", mr: { xs: "15px", md: "25px" } }}
>
Question
</SmallTypo>
<SmallTypo sx={{ fontWeight: "bold" }}>{item.q}</SmallTypo>
</SimpleFlexContainer>
<Box>
<IconButton>
{openDes ? (
<RemoveIcon onClick={() => setDes(false)} />
) : (
<AddIcon onClick={() => setDes(true)} />
)}
</IconButton>
</Box>
</SimpleFlexContainer>
<Box
sx={{
display: openDes ? "inherit" : "none",
background: "white",
p: "26px",
border: "1px solid #F4F4F5",
}}
>
<SmallTypo>{item.a}</SmallTypo>
</Box>
</SimpleFlexContainer>
)
}
Now you can map out your component somewhere else:
{faqData.map((item, index) => <FAQComponent key={item.a} item={item} />)}
NOTE: It's very important for React to put key
argument on mapped components, you can use any other field from item object that's unique.
And after this, use active
constant to determine whether you should change the border or not.
CodePudding user response:
Use state to hold the clicked item's index
const [clicked, setClicked] = React.useState('')
then, you can have a style in one of the outer SimpleFlexContainer
like
sx={{borderColor: clicked === index ? 'your_favourite_color': ''}}
and don't forget to remove the index value when clicked outside or leave it if you don't mind.