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

时间:2017-12-23 03:15:43

标签: javascript reactjs

我试图控制从我的数组渲染的动态复选框。我的问题是我有多个复选框,但我的构造函数中只有一个状态。有没有其他方法可以控制如何在没有

的情况下控制动态字段/项目

以下是我的代码:



  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>
    );
&#13;
&#13;
&#13;

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

3 个答案:

答案 0 :(得分:1)

如果为product数组设置isChecked属性会更好。

我们在这里:

&#13;
&#13;
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')
);
&#13;
<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>
&#13;
&#13;
&#13;

您可以isChecked获得filter()个元素:

let selectedProductsArray = this.state.productsList.filter((product, i)=>{
   return product.isChecked
});

答案 1 :(得分:0)

您为每个复选框设置checkedself.state.addProducts。此属性需要一个布尔值,因此任何truthy值都将导致检查所有框。

checked只有在其值为self.state.product时才应为真。

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

答案 2 :(得分:0)

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

&#13;
&#13;
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')
);
&#13;
<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>
&#13;
&#13;
&#13;