Как правильно сопоставить элемент React с отдельными элементами формы переключателей?

#javascript #reactjs #forms

#javascript #reactjs #формы

Вопрос:

Я пытаюсь создать элемент card, в котором пользователи могут проголосовать «да», «нет» или «возможно» на изображении. Прямо сейчас он читается как переключатели 90 вариантов для одного изображения, а не 30 отдельных с 3 вариантами. Как мне сопоставить каждую карту, чтобы форма соответствовала изображению? Массив будет считываться как

 { userChoices: {
  characterName[0]:choice.value,
  characterName[1]:choice.value,
  ....
}}
  
 const choiceCard = characterData.map((character, key) =>
  <div className="col-sm-12 col-md-3" id="choiceCard" key={character.id}>
    <div id="choiceContent">
      <img src={character.statusImage}/>
      <div id="choice-inner" className="form">
        <span>{character.name}</span>
        <div class="form-check">
          <input 
           class="form-check-input" 
           type="radio" 
           name="yes" 
           id="yes" 
           value="yes"/>
          <label class="form-check-label" for="yes">
            Yes
          </label>
        </div>
        <div class="form-check">
          <input 
           class="form-check-input" 
           type="radio" 
           name="no" 
           id="no" 
           value="no"/>
          <label class="form-check-label" for="no">
            No
          </label>
        </div>
        <div class="form-check disabled">
          <input class="form-check-input" type="radio" name="maybe" id="maybe" value="maybe"/>
          <label class="form-check-label" for="maybe">
            Maybe
          </label>
        </div>
      </div>
    </div>
  </div>
);
  

Ответ №1:

Вы близки к тому, к чему стремились, есть только две вещи, с которыми нужно разобраться здесь:

  1. Связывание каждого набора кнопок с определенным символом.
  2. Отслеживание состояния для каждого символа.

Это естественный вариант использования для управляемых компонентов. Управляемый переключатель будет выглядеть примерно так:

 <input
    key={someID}
    type="radio"
    value={choice}
    checked={this.state.choice === choice}
    onChange={() => this.handleChange(choice)}
/>
  

с обработчиком изменений:

 handleChange = newChoice => {
    this.setState({
        choice: choice
    });
}
  

(см. https://reactjs.org/docs/forms.html )

Применяя это к вашей проблеме, вы получите что-то вроде этого:

 const choices = [
    "Yes",
    "No",
    "Maybe"
]

const choiceCard = characterData.map((character, key) => {
    return (
        <label key={character.id}>
            {character.name}
            {choices.map(choice => {
                return (
                    <input
                        key={choice}
                        type="radio"
                        value={choice}
                        checked={this.state.userChoices[key] === choice}
                        onChange={() => this.handleChange(choice, key)}
                    />
                );
            })}
        </label>
    );
});
  

И следующий обработчик изменений:

 handleChange = (choice, key) => {
    this.setState(prevState => ({
        userChoices: { ...prevState.userChoices, [key]: choice }
    }));
};
  

Вот быстрый и грязный codepen, с которым вы можете поиграть, чтобы лучше понять:https://codepen.io/anon/pen/axzMxm?editors=0010

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

1. Легенда! Настройка second .map сбила меня с толку!! Это идеально