Home > Software design >  How to set border color on individual items on click by map functions?
How to set border color on individual items on click by map functions?

Time:11-22

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.

  • Related