简体   繁体   中英

How do I change 2 states properly in React?

I have 2 spans and state for them:

const Sorter = () => {
  const [sorterTabs, setSorterTabs] = useState([
    {id:'The cheapest', isActive: false },
    {id:'The fastest', isActive: false }
  ])

  const handleSorterClick = ({ target }) => {
    const newSorterTabs = [...sorterTabs]
    newSorterTabs.forEach((item) => {
      if (item.id === target.getAttribute('name')) {
        item.isActive = !item.isActive
      }
    })
    setSorterTabs(newSorterTabs)
  }

  return (
    <>
      {sorterTabs.map((item) => 
        <SorterSpan 
          key={item.id}
          onClick={handleSorterClick}
          name={item.id}
          className={item.isActive ? 'active' : ''}
        />
      )}
    </>
  )
}

const SorterSpan = ({name, onClick, className}) => {
  return (
    <span 
      onClick={onClick} 
      className={className}
      name={name}
    >
      {name}
    </span>
  )
}

I understand how I can change isActive property for each of span. What I need is if I click one span, and it's property isActive becomes true the other span isActive needs to become false and the same for the second span. How to do it properly in handleSorterClick function?

I think the better, cleaner and faster approach for what you're trying to do is this:

const Sorter = () => {
  const sorterTabs = [{ id: "The cheapest" }, { id: "The fastest" }];
  const [selected, setSelected] = useState("");

  const handleSorterClick = ({ target }) => {
    setSelected(target.name);
  };

  return (
    <>
      {sorterTabs.map((item) => (
        <SorterSpan
          key={item.id}
          onClick={handleSorterClick}
          name={item.id}
          className={selected === item.id ? "active" : ""}
        />
      ))}
    </>
  );
};

const SorterSpan = ({ name, onClick, className }) => {
  return (
    <span onClick={onClick} className={className} name={name}>
      {name}
    </span>
  );
};

in this way if you want to grow your spans and wanted to use n span instead of 2 you only need to add them to your sorterTabs variable

I think it would be easier to create a state for each span, map the spans, and control things that way. This way if your app grows you only have to create a new state for each span.... or even use the useContext hook or redux, but that does not apply here. This would be my logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM