根据另一个多值 Select 组件渲染多个 Select 组件

Render multiple Select components depending on another multi value Select component

我有一个多值 Select 组件 (1),我想为当前处于该表单中的每个项目相应地呈现另一个 Select 组件 (2)。即使从 (1) 组件中删除一个项目可以正确地重新呈现 (2) 组件的数量,但 (2) 组件中显示的值不再根据其在 (1) 组件中的对应项目。 (1) 组件中的每个选项都有一个“乘数”键,需要在其对应的 (2) 组件中显示为默认值。如果用户更改 (2) 组件中的值,状态应更新组件 (1) 选项的“乘数”键和状态。

比较难描述,请看下面的动图和下面的代码。 在gif中,右边的Select应该是“1x”、“2x”、“2x”。我的代码可能超级天真,如果有人有一般的意见,欢迎来改进这个反应新手的代码。

Select 数组:

let optionsIngameMode = [
  { value: 'acorn', label: <div><img src={acorn} height={'20px'} width= 
    {'20px'}/>Acorn</div>, multiplicator: 1 },
  { value: 'rose', label: <div><img src={rose} height={'20px'} width={'20px'}/>Rose</div>, 
    multiplicator: 1 },
  { value: 'bell', label: <div><img src={bell} height={'20px'} width={'20px'}/>Bell</div>, 
    multiplicator: 2 },
  { value: 'shield', label: <div><img src={shield} height={'20px'} width= 
    {'20px'}/>Shield</div>, multiplicator: 2 }
 ];

const optionsMultiplicators = [
  { value: 1, label: '1x'},
  { value: 2, label: '2x'},
  { value: 3, label: '3x'},
  { value: 4, label: '4x'},
  { value: 5, label: '5x'},
  { value: 6, label: '6x'},
  { value: 7, label: '7x'},
  { value: 8, label: '8x'},
  { value: 9, label: '9x'},
  { value: 10, label: '10x'},
];

构造函数:

constructor(props) {
  super(props);
  this.state = {
    mode: null,
    lobbyType: null,
    startingCard: null,
    ingameModes: [],
    weis: false,
    crossWeis: null,
    weisAsk: null
  };
  this.handleChange = this.handleChange.bind(this);
};

handleChange 函数:

  handleChange = (selector, event) => {
   switch (selector) {
     case 'multiplicators': {
       console.log(event);
       optionsIngameMode = optionsIngameMode.map(m => {
         if(m === event.mode) {
           return {...event.mode, multiplicator: event.newMult.value};
         }
         return m;
       });
       console.log(optionsIngameMode);
       const updatedIngameModes = this.state.ingameModes.map(m => {
         if(m === event.mode) {
           return {...event.mode, multiplicator: event.newMult.value};
         }
         return m;
       });
       this.setState({ingameModes: updatedIngameModes});
       break;
     };
     case 'modes': {
       const updatedGameModes = optionsIngameMode.filter(m => {
         for(let mode of event) {
           if(mode.label == m.label) {
             return true;
           }
         }
         return false;
       });
       console.log(updatedGameModes);
       this.setState({ingameModes: updatedGameModes});
       break;
     };
   }
 }

Select 组件 (1):

<Select
    styles={customColumnStyle}
    onChange={newModes => this.handleChange('modes', newModes)}
    closeMenuOnSelect={false}
    options={optionsIngameMode}
    defaultValue={optionsIngameMode}
    noOptionsMessage={() => "No game modes selected"}
    isMulti
    autoFocus
/>

Select 组件 (2):

{this.state.ingameModes?.map(mode =>
    <Select
        options={optionsMultiplicators}
        defaultValue={optionsMultiplicators[mode.multiplicator - 1]}
        onChange={newMult => this.handleChange('multiplicators', {mode, newMult})}
    />
)}

除非您提供唯一的 key,否则 React 不会识别列表中 Select 项的 mode。当您删除列表中的任何项目而不为每个项目提供键时,它会删除最后一个,因为它无法区分它们中的任何一个。

key 是一个特殊的属性,即使你没有在 JSX 元素中定义它也总是可用的。

{this.state.ingameModes?.map(mode =>
    <Select
        key={mode.value}
        options={optionsMultiplicators}
        defaultValue={optionsMultiplicators[mode.multiplicator - 1]}
        onChange={newMult => this.handleChange('multiplicators', {mode, newMult})}
    />
)}