Search code examples
javascriptcssreactjstoggletailwind-ui

onClick are open all Text


here is my code, when I click on an Icon(4 icons) they all show text, my 4 icons have the same code structure, I don't know maybe I should add some id ? or do you have a more good choice? can you help me, please :)

 const [showText, setShowText] = useState(false)

  const toggleText = () => setShowText((text) => !text)

   <div className="inline-flex justify-center items-center">
            <Button className=" border-none bg-white" onClick={toggleText}>
              <IconUsers size={30} stroke={1} />
            </Button>
            {showText && (
              <Text className=" inline-flex justify-center items-center align-text-top ">
                devenir member
              </Text>
            )}
          </div>
          <div className="inline-flex justify-center items-center">
            <Button className=" border-none bg-white" onClick={toggleText}>
              <IconHeart size={30} stroke={1} />
            </Button>
            {showText && (
              <Text className="flex justify-center items-center align-text-top ">
                favorites
              </Text>
            )}
          </div>
          <div className="inline-flex justify-center items-center">
            <Button className=" border-none bg-white" onClick={toggleText}>
              <IconMail size={30} stroke={1} />
            </Button>
            {showText && (
              <Text className="flex justify-center items-center align-text-top ">
                notification
              </Text>
            )}
          </div>
          <div className="inline-flex justify-center items-center">
            <Button className=" border-none bg-white" onClick={toggleText}>
              <IconMathSymbols size={30} stroke={1} />
            </Button>
            {showText && (
              <Text className="flex justify-center items-center align-text-top ">
                total
              </Text>
            )}
          </div>

how can I fix it? like click on 1 icon and will only show his own text open 1


Solution

  • Hi you will need to store more information in state. Instead of boolean true false you should store something that can be used as ID, unique to all buttons.

    For example

    const [selected, setSelected] = useState()

    And then toggleText could become toggleSelected and needs to take the id of the element that was selected as an argument.

    const toggleText = (id) => setSelected(id)

    Then in the code for one of the buttons it becomes

    //assuming we call this one with id favorite
    <div className="inline-flex justify-center items-center">
      <Button className=" border-none bg-white" onClick={()=>toggleText("favorite")}>
        <IconHeart size={30} stroke={1} />
      </Button>
      {selected==="favorite" && (
        <Text className="flex justify-center items-center align-text-top">
          favorites
        </Text>
      )}
    </div>
    

    You can then make similar changes for the rest of the buttons giving whatever ids you want. If using typescript you can ensure the state is correct assigned an expected value with something like

    type Option = "favorite" | "membership" | "total" | "notification"
    ...
    const [selected,setSelected] = useState<Option>()
    ...
    const toggleText = (id:Option) => setSelected(id)
    

    This will work and keep the structure as it is. Then eventually what you would probably want is to create a component for that and remove some repetition for the logic.

    Best