anime
anime

Reputation: 165

React toggle visibility of clicked element

I have a simple list of items. When I click on one item I want the text inside span dissapear, but in the rest I want to make them visible. Now when I click on any all spans dissapear. Here is a simple demo: link: https://codepen.io/rosy654/pen/VwaZJNb

Upvotes: 0

Views: 1061

Answers (2)

Leo
Leo

Reputation: 1800

You only have a single value called visible in the state of your Example component and your handleClick funciton updates that value independently of the element clicked. (You're using the same function and same state value for both spans.)

This can easily be solved in two ways:

  1. Creating a new component (example: SpanItem) which only contains the span and the state of that span. You're Example component doesn't need any state in that case and can just render the SpanItem component multiple times.
const SpanItem = ({ label }) => {
  const [visible, setVisible] = useState(true);
  const handleClick = () => {
    setVisible(!visible);
  }
  return <li onClick={handleClick}>{label} <span className={!visible && 'hide'}>Visible</span></li>
}
const Example = () => (
  <div>
    <ul>
      <SpanItem label="First Item">
      <SpanItem label="Second Item">
     </ul>
   </div>
);
  1. You could refactor your usage of the state in the Example component and save one visible value per item:
const Example = () => {
  const defaultVisibillity = true;
  const [visible, setVisible] = useState({});
  
  const isVisible = (id) => visible[id] || defaultVisibillity;

  const handleClick = (id) => () => {
    setVisible({
      ...visible
      [id]: !isVisible(id)
    })
  }
   
    return (
        <div>
        <ul>
          <li id={1} onClick={handleClick(1)}>First Item <span className={!isVisible(1) && 'hide'}>Visible</span></li>                       <li id={2} onClick={handleClick(2)}>Second Item <span className={!isVisible(2) && 'hide'}>Visible</span></li>
        </ul>
        </div>
    );
}

Upvotes: 2

Prathap Reddy
Prathap Reddy

Reputation: 1739

You are using same visible flag/state for both the span items. Hence either both will be hidden or shown at the same time when user clicks any one item,

  • Either use different states like visible1/visible2 and use them respectively
  • Or keep the ids to span element and change code as below inside handleClick
const el = document.getElementById(e.currentTarget.id);
el.style.visibility = "hidden"; // or "visible" accordingly

Upvotes: 1

Related Questions