反应:如何更改地图内拨动开关的状态?

时间:2019-03-06 08:02:36

标签: reactjs

我正在尝试将一组键映射到切换<Switch>组件列表。每个拨动开关的状态都来自redux。当我点击<Switch>时,我希望组件的切换状态会交替出现。

我试图在setState上的onChange处理程序中调用<Switch>,但是它无法正常工作。如何编写将切换开关的功能?

这是我到目前为止所拥有的:

{Object.keys(all_product).map((item, index) => {
  console.log(all_product[item]);
  let product = all_product[item];
  this.state.activevalue = product.is_active;
  let val;

  product.is_active == 1 ? (val = true) : (val = false);

  this.state = { checked: val };

  return (
    <tr>
      <th scope="row">{product.id}</th>
      <td>
        <img
          src={`/img/${product.code}.jpg`}
          alt={product.name}
          class="img-fluid dataTableImg"
        />
      </td>
      <td>{product.name}</td>
      <td>{product.brand}</td>
      <td>{product.quantity}</td>
      <td>{product.unit_price}</td>
      <td>
        <Switch
          onChange={() => {
            this.setState({ checked: !val });
          }}
          checked={this.state.checked}
          value={"A"}
        />
      </td>
    </tr>
  );
})}

2 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,则说明您是从redux商店获取all_product地图。 all_products映射在值上包含一个is_active字段,用于确定每个<Switch>组件的初始状态,然后<Switch>由封闭组件内部的状态控制。

假设我的理解是正确的,一个解决方案可能是通过封闭组件中跟踪的键/值来读取和更新每个checked组件的<Switch>属性:

/* Read checked state */
let isChecked = this.state[ item ]

/* Update (toggle) checked state */
this.setState({ [ item ] : !isChecked })

将其与您的代码集成如下所示:

{Object.keys(all_product).map((item, index) => {

  /* Get product */
  const product = all_product[item];

  /* First try to get "checked value" from state */
  let isChecked = this.state[ item ]

  /* If isChecked fetched from state not present or
     then default to the is_active value supplied by
     your redux store */
  if(typeof isChecked === 'undefined') {
      isChecked = product.is_active;
  }

  return (
    <tr>
      <th scope="row">{product.id}</th>
      <td>
        <img
          src={`/img/${product.code}.jpg`}
          alt={product.name}
          class="img-fluid dataTableImg"
        />
      </td>
      <td>{product.name}</td>
      <td>{product.brand}</td>
      <td>{product.quantity}</td>
      <td>{product.unit_price}</td>
      <td>
        { /* Use locally defined isChecked to set checked 
        prop, and update setState to set negated isChecked
        for item by key  */}
        <Switch
          onChange={() => {
            this.setState({ [ item ]: !isChecked });
          }}
          checked={ isChecked }
          value={"A"}
        />
      </td>
    </tr>
  );
})}

答案 1 :(得分:2)

在Switch的handleChange中,还要在回调中传递索引/ id。参见this

import React from "react";
import Switch from "react-switch";
import update from "react-update";

class App extends React.Component {
  constructor(props) {
    super(props);

    //Assuming you've state in your component, that might as well be your redux state
    this.state = {
      all_products: [{ isActive: false, id: 1 }, { isActive: true, id: 2 }]
    };
  }
  handleChange = (activeStatus, itemId) => {
    const productIndex = this.state.all_products.findIndex(function(
      item,
      index
    ) {
      return item.id === itemId;
    });

    let products = [...this.state.all_products];
    let product = { ...products[productIndex] };
    product.isActive = activeStatus;
    products[productIndex] = product;

    //fire a redux action if all_products is stored in redux state
    this.setState({ all_products: products });
  };

  render() {
    const that = this;
    console.log(this.state.all_products);
    return (
      <div>
        {this.state.all_products.map(function(item, index) {
          return (
            <Switch
              checked={item.isActive}
              onChange={isActive => that.handleChange(isActive, item.id)}
            />
          );
        })}
      </div>
    );
  }
}

export default App;