Реагировать DOM - Форма с несколькими <select>, удалить параметр из другого <select>после выбора одного варианта - PullRequest
0 голосов
/ 09 октября 2019

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

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

Вот мой компонент:

import React, { Component } from 'react';

export default class MatchPlayerSelect extends Component {
   state = {
      selectedPlayers: [],
      players: [
         {
            name:"edmiel",
            matches:0,
            wins:0
         },
         {
            name:"willian",
            matches:0,
            wins:0
         },
         {
            name:"gustavo",
            matches:0,
            wins:0
         },
         {
            name:"gabriel",
            matches:0,
            wins:0
         }
     ]
   }

   render() {
      const {players, selectedPlayers} = this.state;

      return (
         <div className="match-player">
            <select onChange={this.setPlayer.bind(this)}>
               <option defaultValue value="">-</option>
               {
                  // i need to filter list here
                  // but this code only list the items on state
                  players.map((player, index) => {
                     return(
                        <option key={index} value={player}>
                           {player.name}
                        </option>
                     )
                  })
               }
            </select>
         </div>
      );
   }

   setPlayer(sender) {      
      this.setState({ selectedPlayer: [...this.state.selectedPlayers, 
      sender.target.value] });
   }

}

Мне нужно, чтобы все выбранные компоненты отображали каждый игрок состояния (уже делаю это в кодевыше). Но, когда выбрано, мне нужно удалить эту выбранную опцию из других входов без удаления из ввода выбора фокуса. Если есть лучшее решение для этого в React, пожалуйста, дайте мне знать, как это сделать.

Мне нужно сделать это, используя инструменты реагирования jsx или vanilla js. Нет JQuery! Вот и все.

Ответы [ 2 ]

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

Используйте # Array.filter и # Array.includes , кроме того, вам нужно применить несколько исправлений к вашему коду, чтобы он работал:

  • В setPlayer измените ключ на selectedPlayers вместо selectedPlayer
  • При отображении массива players в option свойство value должно быть player.name, а не player
players
  .filter(player => !selectedPlayers.includes(player.name))
  .map((player, index) => (
    <option key={index} value={player.name}>
      {player.name}
    </option>
  ));

Полный пример:

class MatchPlayerSelect extends Component {
  state = {
    selectedPlayers: [],
    players: [
      {
        name: 'edmiel',
        matches: 0,
        wins: 0
      },
      {
        name: 'willian',
        matches: 0,
        wins: 0
      },
      {
        name: 'gustavo',
        matches: 0,
        wins: 0
      },
      {
        name: 'gabriel',
        matches: 0,
        wins: 0
      }
    ]
  };

  render() {
    const { players, selectedPlayers } = this.state;

    return (
      <div className="match-player">
        <select onChange={this.setPlayer}>
          <option defaultValue value="">
            -
          </option>
          {players
            .filter(player => !selectedPlayers.includes(player.name))
            .map((player, index) => (
              <option key={index} value={player.name}>
                {player.name}
              </option>
            ))}
        </select>
        <div>{JSON.stringify(selectedPlayers)}</div>
      </div>
    );
  }

  setPlayer = sender => {
    const { selectedPlayers } = this.state;
    this.setState({
      selectedPlayers: [...selectedPlayers, sender.target.value]
    });
  };
}
ReactDOM.render(<MatchPlayerSelect />, document.getElementById('root'));

Edit Q

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

Итак, во-первых, вы должны удалить this.selectPlayer.bind(this) из метода рендеринга, это не хорошо для React, для более подробной информации перейдите по этой ссылке .
В текущей ситуации вам нужно добавитьодин дополнительный массив и в целом он должен выглядеть следующим образом:
1. players - там вы должны оставить всех игроков (этот служит только для фильтрации).
2. filteredPlayers - там вы должны оставить отфильтрованных игроков(это серверы для рендеринга списка опций).
3. selectedPlayersIds - уверен, что массив, в который вы собираете все идентификаторы выбранного игрока.
Каждый раз, когда вы выбираете игрока, вы берете playersмассив и удаление всех выбранных игроков + новый выбранный игрок и присвоить массив filteredPlayers.
фрагмент кода (функция selectPlayer)

const selectedPlayersIds= [...this.state.selectedPlayersIds, newPlayer.id];
this.setState({
  filteredPlayers: this.state.players.filter(player => this.selectedPlayerIds.indexOf(player.id) !== -1),
  selectedPlayersIds
})
...