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

Posted

技术标签:

【中文标题】reactjs 如何处理一个组件中的多个单选按钮组?【英文标题】:How to handle multiple radio button groups in one component in reactjs? 【发布时间】:2018-06-09 09:49:57 【问题描述】:

我正在尝试在单击发送按钮时从多个单选按钮组中发送选定单选按钮 ID 的列表,

我的问题: 我从后端获得选中的单选按钮,然后我应该能够更改单选按钮并发送回后端。但是当我尝试更改单选按钮时它不起作用。

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

这是线框图和代码sn-p:

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>

【问题讨论】:

【参考方案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>

【讨论】:

【参考方案2】:

您无法更改它们的原因是您在此处设置的当前检查状态:

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

我用于这个确切场景的一种方法是将组件的状态(来自服务器)存储在我的组件状态 (this.state) 中,将状态传递给元素:checked=this.state.isChecked,并更新元素的状态 @987654324 @。

例子:

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.如果你看到卡片阵列,它怎么知道哪个收音机 它所属的按钮组。

我们可以根据单选按钮的名称修改状态。

让我们将所有卡片保存在组件的状态中。我知道卡片是从服务器检索的,并将使用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);

【讨论】:

这个答案可能适用于单个单选按钮组,但我面临多个单选按钮组中的多个单选按钮的问题。如果您看到卡片数组,它如何知道哪个单选按钮组它属于。 如果我们有一个动态的状态,我们不知道从后端会得到多少张卡片?我正在尝试结束。一旦我得到完美的,我可能会发布。 @user8208248 只要您将获取的数据保存到您的状态,就可以了。

以上是关于reactjs 如何处理一个组件中的多个单选按钮组?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ReactJS 中一个组件的 css 文件与另一个组件的 css 文件交互?如何处理?

reactjs中如何处理this.setState问题

如何处理 ReactJS 中的 `onKeyPress` 事件?

如何处理 React js 并发?

使用组件依赖时如何处理多个 Dagger 组件

在 monorepo 中的多个应用程序之间共享组件时如何处理共享依赖项