S
S
Sergey2021-03-05 17:27:27
React
Sergey, 2021-03-05 17:27:27

How to change the state of the entire list of elements except for one in React?

There is a list of cards with a button on each. By clicking on the button, I change the state and add a class to the corresponding card.
I would like to drop the state from the entire collection by clicking on the button and put it only in the clicked card.

The card itself:

class ServiceCard extends React.PureComponent {
constructor(props) {
  super(props);

  this.state = {
    isServiceFormOpen: false,
  };
}

clickServiceCardBtn() {
  this.setState({
    isServiceFormOpen: true,
  });
}
render() {
  return (
           <div className={cn("service-card", { "--opened": this.state.isServiceFormOpen })}>
                <button 
                     className="service-card__btn" 
                     onClick={this.clickServiceCardBtn}
                >
                   Кнопка
               </button>
           </div>
         )}
}


And there is a parent with a card call:
<div className="service-list">
          {serviceCards.map((card, index) => {
            return (
              <React.Fragment key={"service-card" + index}>
                <ServiceCard
                  clickServiceCard={this.clickServiceCard}
                  extraClass="service-list__card"
                />
              </React.Fragment>
            );
          })}
</div>

Answer the question

In order to leave comments, you need to log in

2 answer(s)
L
LEXA_JA, 2021-03-05
@DaveGarrow

You need to raise the state to the parent:

this.state = {
    openedServiceFormIndex: -1,
  };

  clickServiceCard(index) {
    this.setState(
      prevState => {
        if (index === prevState.openedServiceFormIndex) {
          return {
            openedServiceFormIndex: -1,
          }
        } else {
          return {
            openedServiceFormIndex: index,
          }
        }
      }
    );
  }

  render() {
  <div className="service-list">
          {serviceCards.map((card, index) => {
            return (
              <React.Fragment key={"service-card" + index}>
                <ServiceCard
                  opened={index === this.state.openedServiceCardIndex}
                  clickServiceCard={() => this.clickServiceCard(index)}
                  extraClass="service-list__card"
                />
              </React.Fragment>
            );
          })}
</div>
  }

And remove from the card
render() {
  return (
           <div className={cn("service-card", { "--opened": this.props.opened})}>
                <button 
                     className="service-card__btn" 
                     onClick={this.props.clickServiceCard}
                >
                   Кнопка
               </button>
           </div>
         )}
}

V
Vladimir, 2021-03-05
@Casufi

Consider using context API or redux

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question