开发者问题收集

如何控制 Reactjs 中的动态复选框?

2017-12-23
23688

我尝试控制从我的数组呈现的动态复选框。我的问题是我有多个复选框,但我的构造函数中只有一个状态。有没有其他方法可以控制动态字段/项目,而无需

以下是我的代码:

onAddingItem = (item) =>{
    var self = this;
    const value = item.target.type === 'checkbox' ? item.target.checked : item.target.value;
    var newArray = self.state.product.slice();
    if(item.target.checked){
        newArray.push(item.target.value);
        self.setState({addProducts:value, product:newArray})
    } else {
      newArray.splice(item.target.value, 1); //remove element
      self.setState({addProducts:value, product:newArray}); //update state
    }
  }

  render(){
    var self = this;
    const {title, photo, photoHeight, photoWidth, showPhoto, editorState, description, editorData, productsList} = this.state;
    const product_list = productsList.map((index, i) =>
      <tr key={i+1}>
        <td>{i+1}</td>
        <td>{index.name}</td>
        <td>
            <div class="checkbox checkbox-circle checkbox-color-scheme">
                <label class="checkbox-checked">
                    <input type="checkbox" value={index.name} checked={self.state.addProducts} onChange={this.onAddingItem}/> <span class="label-text">Add ?</span>
                </label>
            </div>
        </td>
      </tr>
    );

每当我选中其中一个复选框时。所有其他复选框也被选中。如您所见,我想在复选框被选中时将其值添加到数组中,并在复选框未选中时从数组中删除现有值。

3个回答

如果为产品数组设置 isChecked 属性,效果会更好。

我们在这里:

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      productsList :[
        {name: 'USS Seawolf class', isChecked: false},
        {name: 'USS Skipjack', isChecked: false},
        {name: 'USS Lafayette', isChecked: false},
        {name: 'USS Ohio class', isChecked: false},
      ]
    }
  }
  
  onAddingItem = (i) => (event) => {
    this.setState((state, props) => {
      state.productsList[i].isChecked = !state.productsList[i].isChecked;
      return {
        productsList: state.productsList
      }
    })
  }

  render() {
    let {productsList} =  this.state;
    return (
      <table>
        <tbody>
          { productsList.map((product, i) =>{
            return(
              <tr key={i+1}>
                <td>{i+1}</td>
                <td>{product.name}</td>
                <td>
                    <div class="checkbox checkbox-circle checkbox-color-scheme">
                        <label class="checkbox-checked">
                            <input type="checkbox" value={product.name} checked={product.isChecked} onChange={this.onAddingItem(i)}/> <span class="label-text">Add ?</span>
                        </label>
                    </div>
                </td>
            </tr>
            )
          })}
          
        </tbody>
      </table>
    )
  }
}

ReactDOM.render( <
  App / > ,
  document.getElementById('app')
);
<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="app">
  <!-- This element's contents will be replaced with your component. -->
</div>

并且您可以通过 filter() 获取 isChecked 元素:

let selectedProductsArray = this.state.productsList.filter((product, i)=>{
   return product.isChecked
});
Emad Emami
2017-12-23

我同意 Emad 在每个对象内添加一个属性来控制每个复选框,但是请确保在更新这些值时不要改变状态。

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      productsList: [{ name: "Product A", isAdded: false }, { name: "Product B", isAdded: false }, { name: "Product C", isAdded: false }],
      addedProducts: []
    }
  }

  onAddingItem = (item) => {
    const isChecked = item.target.checked;
    const value = item.target.value;

    this.setState(prevState => ({ productsList: prevState.productsList.map(product => product.name === value ? { ...product, isAdded: isChecked } : product) }));

    if (isChecked)
      this.setState(prevState => ({addedProducts: [...prevState.addedProducts, value] }));
    else {
      const newAddedProducts = this.state.addedProducts.filter(product => product !== value)
      this.setState({ addedProducts: newAddedProducts });
    }
  }
  
  render() {
    const { productsList } = this.state;
    const product_list = productsList.map((index, i) =>
      <tr key={i + 1}>
        <td>{i + 1} - </td>
        <td>{index.name}</td>
        <td>
          <div class="checkbox checkbox-circle checkbox-color-scheme">
            <label class="checkbox-checked">
              <input type="checkbox" value={index.name} checked={this.state.productsList[i].isAdded} onChange={this.onAddingItem} /> <span class="label-text">Add ?</span>
            </label>
          </div>
        </td>
      </tr>
    );

    return (
      <div>
        <table>
          <tbody>
            {product_list}
          </tbody>
        </table>
        <div style={{ marginTop: "20px" }}>Added Products: {this.state.addedProducts.join(', ')}</div>
      </div>
    )
  }
}

ReactDOM.render( <
  App / > ,
  document.getElementById('app')
);
<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="app">
  <!-- This element's contents will be replaced with your component. -->
</div>
Henry
2017-12-23

您正在将每个复选框的 checked 设置为 self.state.addProducts 。此属性需要一个布尔值,因此任何真值都会导致选中所有复选框。

checked 的值在 self.state.product 中时才应为真。

编辑:也许是这样的? checked={self.state.product.includes(item.value)

russpol
2017-12-23