Ошибка «Два ребенка с одним и тем же ключом» при попытке заполнить выпадающий список - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь создать раскрывающийся список с множественным выбором с помощью Semantic UI и React, который динамически выбирает данные из API. Ему успешно удается извлечь данные, но когда я снова ищу те же данные, он снова добавляет их в список параметров, и я получаю консольную ошибку «два ребенка с одним и тем же ключом».

Iдобавлено исключение «if (! this.state.options.include (e))», но, по-видимому, это не помогает.

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

  getOptions = () => {

      if(this.state.searchQuery) {
          this.setState({isFetching:true})
          axios.get('URL', {
              params: {
                  query: this.state.searchQuery,
                  api_key: KEY
              }
          })  

          .then( (response) => {

              this.setState((prevState)=>({

                  options: [
                  ...response.data.results.map( (e) => {  

                      if (!this.state.options.includes(e)) {
                          return {

                              key: e.id,
                              text: e.name, 
                              value: e.id
                          }   
                      }

                  })
                  , ...prevState.options]

              }), () => this.setState({isFetching:false}))

          }).catch(function () {
              return
          })
      }
  }


handleChange = (e, { value }) => {this.setState({ value })}
handleSearchChange = (e, { searchQuery }) => {
    this.setState({ searchQuery }, () => {this.getOptions()}
  )}

render() {
  const { options, isFetching, search, value } = this.state

  return (
      <Grid>
          <Grid.Column width={5}>
          <Dropdown
              fluid
              onAddItem={this.handleAddition}
              selection
              multiple
              search={search}
              options={options}
              value={value}
              placeholder="Search keywords"
              onChange={this.handleChange}
              onSearchChange={this.handleSearchChange}
              disabled={isFetching}
              loading={isFetching}
          />
          </Grid.Column>
      </Grid>
      )
  }

Я бы хотел, чтобы меню параметров не добавляло те же результаты поиска в список параметров, который ужекогда я снова ищу те же данные.

1 Ответ

0 голосов
/ 27 октября 2019

Обновлен этот ответ, потому что я считаю, что проблема в том, что map как есть, либо вернет объект с нужной информацией, либо не вернет ничего. В последнем случае элемент не будет удален, он просто будет неопределенным. Попробуйте выполнить следующее, которое выполняет операцию в два этапа: отфильтровывает результаты до уникальных результатов, а затем выполняет настройку состояния только с этими уникальными значениями.

const unique = response.data.results.filter(e => {
  return !this.state.options.some(el => el.id === e.id);
});

this.setState(prevState => ({
  options: [
    ...unique.map(e => ({
      key: e.id,
      text: e.name, 
      value: e.id
    }), 
    ...prevState.options
  ]
}));

Это может быть неэффективнымспособ проверить, как вы могли бы перебирать множество существующих результатов. Если у вас возникают проблемы с производительностью, вы можете подумать о том, чтобы сохранить результаты поиска в виде объекта или использовать что-то вроде Set для повышения эффективности поиска в хэш-таблице.

...