Change state to unselected for all other except selected

Viewed 34

I have list of message. I create custom component for that. I changed background color in selection of Item. But, not found way to reset background on another item selection.

Suppose I select first Item it changes to isSelected = true but,on second select it change 2nd to isSelected = true but, I want first(Or all other) isSelected = false.

const Container = styled.div`
  width: auto;
  cursor: pointer;
  :hover {
    background-color: #ccc;
    border-radius: 5px;
  }

  ${({ isSelected }) =>
    isSelected &&
    `
    background-color: #b4b4b4`}

`;

const SomeText = styled.span`
  color: #000000

    ${({ isSelected }) =>
        isSelected &&
        `
        color: #ffffff;`}
`;

const Message = ({ item, onItemClick }) => {
  const [isSelected, setIsSelected] = useState(false);

  const onClick = data => {
    onItemClick(data);
    setIsSelected(true);
  };

 return (
  <Container isSelected={isSelected} onClick={onClick}>
   <SomeText isSelected={isSelected}>{item.text}            </SomeText>
  </Container>
 )
};

Parent component:

return (
    <div>
        {list.map(item => {
          return <Message item={item} key={item.id} onItemClick={onItemClick}/>;
        })}
    </div>
  );

Is there any good way I can make isSelected = false all other except selected on. Any help would be greatly appreciated.

1 Answers

You need to lift the "selected" state one level up. So, when you select a message, every message knows which is the selected one:

const Container = styled.div`
  width: auto;
  cursor: pointer;
  :hover {
    background-color: #ccc;
    border-radius: 5px;
  }

  ${({ selected }) =>
    selected &&
    `
    background-color: #b4b4b4`}

`;

const SomeText = styled.span`
  color: #000000

    ${({ selected }) =>
        selected &&
        `
        color: #ffffff;`}
`;

const Message = ({ item, onItemClick, selected, setSelected }) => {
  const onClick = data => {
    onItemClick(data);
    setSelected();
  };

 return (
  <Container selected={selected} onClick={onClick}>
   <SomeText selected={selected}>{item.text}            </SomeText>
  </Container>
 )
};

Parent component:
  const [selected, setSelected] = useState(null);
  return (
    <div>
        {list.map(item => {
          return <Message
            item={item}
            key={item.id}
            onItemClick={onItemClick}
            selected={selected === item.id}
            setSelected={() => setSelected(item.id)
          />;
        })}
    </div>
  );

Related