Как предотвратить одновременный вызов нескольких зацикленных выходных данных в React?

#javascript #reactjs #loops

#javascript #reactjs #циклы

Вопрос:

Я перебираю tds таблицы, и каждая ячейка в нижней строке представляет собой бизнес-описание с a …Подробнее ссылка, которая открывает модальный. Когда я нажимаю на один, он открывает не только модальный для этой ячейки, но и все из них и, как ни странно, начинается с последнего. Пожалуйста, посмотрите это видео для демонстрации:

https://youtu.be/M_EDh_jAWaw

Вот код:

   state = {
    showModal: false
  };

  toggleModal = () => {
    this.setState({showModal: true});
    console.log('showModal: ', this.state.showModal);
  }
  

И:

   <tr style={{height: '132px'}}>
    {assignedServiceProviders.map((provider, index) => {
      return (
        <td key={index}>
          <Truncate lines={5} ellipsis={<span>... <a onClick={this.toggleModal} key={index}>Read more</a></span>}>
            {provider.description} asfasfdadfdas 46465464 adaddafafdadf 4654564564564 adsadfdafafdfd
          </Truncate>
          <If condition={this.state.showModal}>
            <AutomaticModalTrigger modal={businessDescriptionModal(provider.description)} key={index}>
              <span style={{ display: 'none' }} />
            </AutomaticModalTrigger>
          </If>
        </td>);
    })}
  </tr>
  

Когда я нажимаю на ссылку, ей просто нужно открыть только соответствующее описание бизнеса, а не какие-либо другие! Кто-нибудь знает, как предотвратить такое поведение?

Комментарии:

1. Может быть, иметь ShowModal состояние для каждого модального, или пусть они будут ключами на showmodalобъекте.

Ответ №1:

Проблема в том, что вы создаете несколько экземпляров модалов, когда выполняете цикл над своими assignedServiceProviders. Я не думаю, что вам нужно несколько экземпляров, поскольку вы будете открывать только один за раз.

Когда вы устанавливаете состояние modal на ShowModal. Фактически вы устанавливаете состояние для всех экземпляров сгенерированных модалов. Следовательно, вы в конечном итоге открываете несколько модалов. В идеале у вас должен быть только один модал, и вы должны передавать данные в свой модал.

Вы можете сделать это:

Во-первых, выведите модал из цикла, чтобы у вас был только один его экземпляр.

Передавать данные в:

  <a>onClick={() => this.toggleModal(provider.description)} key={index}>Read more</a> 
  

Наконец, в функции toggleModal сначала задайте описание, а затем откройте modal .

Таким образом, все ваши ссылки ReadMore в конечном итоге будут вызывать один и тот же модальный экземпляр. Но с разными описаниями. После того, как вы зададите описание, вы можете повторно отобразить свой компонент с уже существующим состоянием ShowModal.

Вот небольшой пример:

 class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      showModal: false,
      description: ''
    }
    this.list = [{description: 'desc1'}, {description: 'desc2'}];
  }

  onAnchorClick({description},event){
    this.setState({description, showModal: true});
  }

  render(){
    return(
      <div>
        {this.list.map((obj, idx) => <div key={idx}>
          <a onClick={this.onAnchorClick.bind(this, obj)}>Read More</a>
        </div>)}

        <div style={{display: !this.state.showModal ? 'none' : 'block'}}>
          <h3>Description: {this.state.description}</h3>
        </div>
      </div>
    )
  }
}

window.onload = () => {
    ReactDOM.render(<App />, document.getElementById("app"));
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>