it-swarm.com.ru

Как обрабатывать несколько групп переключателей в одном компоненте в responsejs?

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

Моя проблема: Я получаю выбранную радиокнопку из бэкэнда, затем я могу сменить радиокнопку и отправить обратно в бэкэнд. но когда я пытаюсь изменить переключатель, он не работает.

Чего я не понял: Как работать с функцией при изменении, обычно при изменении мы можем изменить состояние, но чтобы изменить состояние при нагрузке, мы должны получить переключатели значений. Наконец меня тут поразили, не понимая, как двигаться вперед.

Вот каркас и фрагмент кода:

wireframe

function CardsList(props) {
  const cards = props.cards;
  return (
    <div>
      {cards.map((card, idx) => (
       <div>
         {card.cardName}
          {
            card.options.map((lo,idx) => (
              <li key={idx}>
              <input
                 className="default"
                 type="radio"
                 name={card.cardName}
                 checked={lo.selected}
             />))
          }
         <div>
       ))}
   </div>
  );
}
//array of cards coming from the backend
const cards = [
{cardName:'card1',options:[{radioName:'card1-radio1',selected:'true'},
                          {radioName:'card1-radio2',selected:'false'}]},
  {cardName:'card2',options:[{radioName:'card2-radio1',selected:'true'},
                          {radioName:'card2-radio2',selected:'false'}]}
];
ReactDOM.render(
  <CardsList cards={cards} />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
6
sravan kumar ganji

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

Важный! - Здесь следует заметить, что я изменил тип свойства selected с String на Boolean. это позволит мне справиться с такими условиями:

<input checked={option.selected} />

Если вы не можете изменить его на Boolean, вам нужно обработать условие следующим образом: 

<input checked={option.selected === 'true'} />

Вот бегущий пример:

//array of cards coming from the backend
const data = [
  {
    cardName: 'card1', options: [{ radioName: 'card1-radio1', selected: true },
    { radioName: 'card1-radio2', selected: false }]
  },
  {
    cardName: 'card2', options: [{ radioName: 'card2-radio1', selected: true },
    { radioName: 'card2-radio2', selected: false }]
  }
];


class CardsList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cards: []
    };
  }

  componentDidMount() {
    setTimeout(() => {
      // mimic an async server call
      this.setState({ cards: data });
    }, 1000);
  }

  onInputChange = ({ target }) => {
    const { cards } = this.state;
    const nexState = cards.map(card => {
      if (card.cardName !== target.name) return card;
      return {
        ...card,
        options: card.options.map(opt => {
          const checked = opt.radioName === target.value;
          return {
            ...opt,
            selected: checked
          }
        })
      }
    });
    this.setState({ cards: nexState })
  }

  onSubmit = () => { console.log(this.state.cards) };

  render() {
    const { cards } = this.state;
    return (
      <div>
        {
          cards.length < 1 ? "Loading..." :
            <div>
              {cards.map((card, idx) => (
                <ul>
                  {card.cardName}
                  {
                    card.options.map((lo, idx) => {
                      return <input
                        key={idx}
                        type="radio"
                        name={card.cardName}
                        value={lo.radioName}
                        checked={!!lo.selected}
                        onChange={this.onInputChange}
                      />

                    })
                  }
                </ul>
              ))
              }
              < button onClick={this.onSubmit}>Print Cards</button>
            </div>
        }

      </div>
    );
  }
}

ReactDOM.render(<CardsList />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

1
Sagiv b.g

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

<input
  className="default"
  type="radio"
  name={card.cardName}
  checked={lo.selected}
/>

Подход, который я использовал для этого точного сценария, заключается в сохранении состояния компонента (с сервера) в состоянии моего компонента (this.state), передаче состояния в элемент: checked={this.state.isChecked} и обновлении состояния элемента onClick.

Пример:

class CardsList extends Component {
  constructor(props){
    super(props);
    this.state = {isChecked: false};
    this.inputOnClick = this.inputOnClick.bind(this);
  }
  //fetch data from server
  fetchData(){
    fetch('/api')
      .then(res => res.json())
      //this will be our initial state
      .then(res => this.setState(res))
  }
  componentDidMount(){
    this.fetchData();
  }
  //change radio button state on click
  inputOnClick(e){
    e.preventDefault();
    //invert state value
    this.setState((prevState, props) => {isChecked: !prevState.isChecked});
  }
  render(){
    return (
      <input
        type="radio"
        checked={this.state.isChecked}
        onClick={this.inputOnClick}
       />
      )
   }
}

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

Мы можем изменить состояние на основе имени переключателя. 

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

this.state = {cards: [
  { cardName:'card1',
  options:[
    {radioName:'card1-radio1',selected:true},
    {radioName:'card1-radio2',selected:false}
   ]
  },
  { cardName:'card2',
    options:[
      {radioName:'card2-radio1',selected:true},
      {radioName:'card2-radio2',selected:false}
     ]
    }
]}

Теперь, когда мы щелкаем по переключателю, мы будем использовать имя этого переключателя, чтобы обновить состояние, в котором оно должно быть обновлено. Поскольку состояние React должно быть неизменным, мы создадим глубокую копию состояния, изменим его и затем установим состояние с ним.

inputOnClick(e){
  e.preventDefault();
  var thisRadioBtn = e.target.name;
  //make a deep copy of the state
  const stateCopy = JSON.parse(JSON.stringify(this.state.cards));
  //go through state copy and update it
  stateCopy.forEach(card => {
    card.options.forEach(option => {
      if(option.radioName === thisRadioBtn){
        //invert value
        //make sure the values are booleans
        option.selected = !option.selected;
      }
    });
  });
  //update the components state
  this.setState({cards: stateCopy});
}
1
Josan Iracheta