Change html attribute value does not have data with onclick event using react

Viewed 144

I have these code,

export default MainContent = () => {
    handleClick = (e) => {
        const attr = e.target.getAttribute("aria-expanded");
    };

    return (
        <div aria-expanded='false' onClick={handleClick}>1</div>
        <div aria-expanded='false' onClick={handleClick}>2</div>
        <div aria-expanded='false' onClick={handleClick}>3</div>    
    );
}

What I need to do is set aria-expanded='true' when click. I can't make this to data-expanded. And I only need to change clicked item. Is there any way to do this?

2 Answers

You can create a new state, which you will change with onClick function and the value of aria-expanded will be dependent on this state

export default MainContent = () => {
  const [open, setOpen] = useState(false);
  const handleClick = (e) => {
    setOpen(!open);
    e.target.setAttribute("aria-expanded", open);
  };

    return (
        <div aria-expanded={expanded ? 'true' : 'false' } onClick={handleClick}>1</div>
        <div aria-expanded={expanded ? 'true' : 'false' } onClick={handleClick}>2</div>
        <div aria-expanded={expanded ? 'true' : 'false' } onClick={handleClick}>3</div>    
    );
}

Working Demo

First you need to wrap divs. Then set event to the wrapper to delegate it. Finally, have get the data from the attribute, handle it and putting back.

const MainContent = () => {
  const handleClick = (e) => {
    const attr = e.target.getAttribute("aria-expanded");
    // Check for attributes
    if (!attr) {
      return;
    }
    // Switch status
    const changeAttr = attr === "false" ? "true" : "false";
    // Set result back
    e.target.setAttribute("aria-expanded", changeAttr);
  };

  return (
    <section className="container" onClick={handleClick}>
      <div aria-expanded="false">1</div>
      <div aria-expanded="false">2</div>
      <div aria-expanded="false">3</div>
    </section>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(
    <MainContent />,
  rootElement
);
div {
  display: flex;
  flex-flow: column;
  text-align: center;
  gap: 0.5em;
  padding: 1em;
  cursor: pointer;
}

div[aria-expanded="false"] {
  background-color: rgb(255, 179, 0);
}

div[aria-expanded="true"] {
  background-color: rgb(89, 0, 255);
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related