如何在reactjs中的一个组件中处理多个单选按钮组?

时间:2017-12-28 21:06:13

标签: javascript html reactjs ecmascript-6

我正在尝试通过点击发送按钮从多个单选按钮组发送所选单选按钮ID的列表,

我的问题: 我从后端获得选择单选按钮,然后我应该能够更改单选按钮并发送回后端。但是当我尝试更改单选按钮时,它无法正常工作。

我不明白的是: 如何处理on更改功能,通常在更改时我们可以更改状态但是要在加载时更改状态我们应该抓取值单选按钮。最后我被击中了,不知道如何前进。

以下是线框和代码段:

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>

2 个答案:

答案 0 :(得分:1)

您无法更改这些内容的原因是因为您在此处设置了当前检查状态:

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

我在这个确切场景中使用的方法是将组件的状态(来自服务器)存储在组件的状态(this.state)中,将状态传递给元素:{ {1}},并更新元素的状态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} /> ) } } 保存,但出于视觉目的我这样写。

setState

现在,当我们点击单选按钮时,我们将使用该单选按钮的名称来更新需要更新的状态。由于React状态需要是不可变的,我们将创建状态的深层副本,修改它,然后用它设置状态。

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}
     ]
    }
]}

答案 1 :(得分:1)

您可以将对象用作将组名称作为键的查找表 在每次更改时,您都需要找到具有相关选项的相关组,并相应地设置新状态。

重要! - 有一点需要注意的是,我将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>