反应DOM-具有多个<select>的表单,选择一个选项后从另一个<select>中删除选项

时间:2019-10-09 14:49:55

标签: javascript arrays reactjs drop-down-menu state

我有一个带有4个输入的表格,这些输入使用了来自同一状态的数据。我想要的是,选择之后,choose选项将从另外3个选择中删除。

我尝试了很多事情,很难在这里列出,但是总而言之:我创建了另一个选中选项列表,用另一个列表过滤玩家数组,映射了这个等等。

此方法的问题是:我不想从选定的输入中删除选定的项目。因此,我尝试为每个输入创建相同原始列表的副本。但是,我认为这种方式太“变通”了。

这是我的组成部分:

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中存在更好的解决方案,请告诉我。

我需要使用react jsx工具或普通js来执行此操作。没有jquery! 就是这样。

2 个答案:

答案 0 :(得分:0)

因此,首先,您应该从render方法中删除this.selectPlayer.bind(this),这对React不利,有关更多信息,请遵循此link
在当前情况下,您需要添加一个额外的数组,整个数组看起来应该像这样:
1. players-您应该保留所有播放器(该播放器仅用于过滤)。
2. filteredPlayers-您应该保留经过过滤的播放器(该服务器用于呈现选项列表)。
3. selectedPlayersIds-确保您收集所有选定玩家ID的阵列。
每次选择一个玩家时,您都会使用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
})

答案 1 :(得分:0)

使用#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