【问题标题】:How to Update JSON Object's state for onChange event in REACT JS?如何在 REACT JS 中为 onChange 事件更新 JSON 对象的状态?
【发布时间】:2019-09-21 14:39:34
【问题描述】:

我有 myrecords[] 状态,其中包含以下格式的 JSON 对象:

{
    "records": {
        "Master Automotives": [
            {
                "SparePartID": "43",
                "Name": "Oil and Lubricants",
                "Price": "4500",
                "VendorID": "48",
                "CompanyName": "Master Automotives",
                 "Qty": 1,
                 "TotalPrice": "4500"

            },
            {
                "SparePartID": "45",
                "Name": "Lights",
                "Price": "2300",
                "VendorID": "48",
                "CompanyName": "Master Automotives",
                 "Qty": 1,
                 "TotalPrice": "2300"
            }
        ],
        "Repair Solutions": [
            {
                "SparePartID": "47",
                "Name": "Steering Wheel",
                "Price": "1500",
                "VendorID": "60",
                "CompanyName": "Repair Solutions",
                 "Qty": 1,
                 "TotalPrice": "1500"
            }
        ],
        
         "FiveStar Automotives": [
            {
                "SparePartID": "51",
                "Name": "Brakes",
                "Price": "234",
                "VendorID": "70",
                "CompanyName": "FiveStar Automotives",
                 "Qty": 1,
                 "TotalPrice": "234"
            },
            {
                "SparePartID": "53",
                "Name": "Clutch",
                "Price": "999",
                "VendorID": "70",
                "CompanyName": "FiveStar Automotives",
                 "Qty": 1,
                 "TotalPrice": "999"
            },
              {
                "SparePartID": "55",
                "Name": "LED",
                "Price": "288",
                "VendorID": "70",
                "CompanyName": "FiveStar Automotives",
                 "Qty": 1,
                 "TotalPrice": "288"
            }
        ]
    }
}

现在我在 react js 中显示这条记录,所有项目都显示在行中并按它们的 CompanyNames 分组,并且每个项目都有一个数量的输入字段。 默认数量为 1,因此 TotalPrice 与 UnitPrice 相同。

现在我想要 Qty 的任何特定输入字段的 onChange,JSON Object 中相应的 TotalPrice 项也应该在myrecords[] 状态。此外,Qty 也应该在 myrecords[] 状态下更新。

P.S:myrecords[] 包含 JSON object 而不是数组。

这是我的显示 JSON 对象记录的反应代码

  
  {Object.keys(this.state.myrecords).map((CompanyName, i) => (
<div key={CompanyName}>
   <h2>Supplier: {CompanyName}</h2>
   
  {this.state.myrecords[CompanyName].map((product, i) => (
  <tr>

    <td>
      <h4> {product["SparePartID"]} </h4>
    </td>

    <td>
      <h4>{product["Name"]} </h4>
    </td>

    <td>
      <h4> {product["Price"]} </h4>
    </td>

    <td>
      <input type="number"
      value={product["Qty"]}
      min="1"
      onChange={(e) => this.onChangeQty(product["SparePartID"], e)}/>
    </td>

    <td> $ {product["TotalPrice"]}
    </td>

  </tr>
  ))}
  
  </div>

  ))}

onChangeQty函数如下**(这里是我需要帮助的地方)**:

onChangeQty(sid,e)
{
   const items = this.state.myrecords;
  const item = items.find(item => item.SparePartID === sid);
  item.Qty = e.target.value;
  item.TotalPrice = item.Qty * item.Price;

  this.setState({
     myrecords: items
   });
}

【问题讨论】:

    标签: javascript json reactjs state onchange


    【解决方案1】:

    问题是this.state.myrecords是一个对象,所以我们不能直接使用find。您还需要使用updater function (check doc for more details)

    您的问题的解决方案是:在 onChange 函数中也传递 companyName,然后仅运行特定公司详细信息数组的循环。传递公司名称将帮助您轻松更新状态,否则您需要在所有数组上运行循环。

    像这样:

    onChange={(e) => this.onChangeQty(product["SparePartID"], CompanyName, e)}
    
    onChangeQty(sid, companyName, e) {
      const value = e.target.value;
      this.setState(prevState => {
    
        return {
          myrecords: {
            ...prevState.myrecords,
            [companyName]: prevState.myrecords[companyName].map(el => {
              if(el.SparePartID === sid) {
                return { ...el, Qty: value, TotalPrice: (el.price * value) }
              }
              return el;
            });
          }
        }
      };
    }
    

    【讨论】:

      【解决方案2】:

      先改一下

      {this.state.myrecords[CompanyName].map((product, i) => (
      

      {this.state.myrecords[CompanyName].map((product, j) => (
      

      因为我们已经在上面的地图中使用了 i

      然后改这个

      onChange={(e) => this.onChangeQty(product["SparePartID"], e)}
      

      onChange={(e) => this.onChangeQty(CompanyName, j, e)}
      

      然后你的 onChange 应该是

      onChangeQty(CompanyName,j,e)
      {
         const items = {...this.state.myrecords};
        items[CompanyName][j].Qty = e.target.value;
        items[CompanyName][j].TotalPrice = e.target.value * items[CompanyName][j].Price;
      
        this.setState({
           myrecords: items
         });
      }
      

      如果您不喜欢基于 onChange 的索引,您也可以执行以下操作(基于 sid)。只需在此函数上传递CompanyName,sid,e) onChange={(e) =&gt; this.onChangeQty

      onChangeQty(CompanyName,sid,e)
      {
         const items = {...this.state.myrecords};
        const j = items[CompanyName].findIndex(item => item.SparePartID === sid);
        items[CompanyName][j].Qty = e.target.value;
        items[CompanyName][j].TotalPrice = e.target.value * items[CompanyName][j].Price;
      
        this.setState({
           myrecords: items
         });
      }
      

      警告:代码未经测试。请检查并告诉我:)

      【讨论】:

      • 谢谢拉胡尔。它解决了我的问题。我还有一个问题:如果我想为每个公司的项目分别设置一个 GrandTotal,比如我有 3 个公司项目,我想将每个公司的总计保存在 3 个不同的州并分别显示(因为我想分别处理每个公司的订单) .怎么做?请回复
      • 你想在哪里显示&lt;td&gt;Grand Total: $ {this.state.myrecords[CompanyName].reduce((oldValue, product) =&gt;product.TotalPrice+oldValue,0)} &lt;/td&gt;。您也可以在单独的函数中编写此逻辑。查看更多关于reducehere。我希望你明白了:)。如果觉得有帮助,请点赞
      • 谢谢,但这只是连接我的所有价格而不是总和。或者有没有其他方法可以将所有总计保存在一个带有索引的数组中并以索引方式获取它?
      • 它们是串联的,因为它们是字符串。添加加号reduce((oldValue, product) =&gt;+product.TotalPrice+oldValue,0)
      • 感谢 parseInt 解决了这个问题。但是我怎样才能将所有这些总和存储在一个状态或数组中?因为我想稍后在订单处理中使用它们。 :(
      【解决方案3】:

      您正在尝试在this.state.myrecord 中查找项目。但是你应该在特定的公司。这是DEMO

      import React from "react";
      import ReactDOM from "react-dom";
      
      const RECORDS = {
        "Master Automotives": [
          {
            SparePartID: "43",
            Name: "Oil and Lubricants",
            Price: "4500",
            VendorID: "48",
            CompanyName: "Master Automotives",
            Qty: 1,
            TotalPrice: "4500"
          },
          {
            SparePartID: "45",
            Name: "Lights",
            Price: "2300",
            VendorID: "48",
            CompanyName: "Master Automotives",
            Qty: 1,
            TotalPrice: "2300"
          }
        ],
        "Repair Solutions": [
          {
            SparePartID: "47",
            Name: "Steering Wheel",
            Price: "1500",
            VendorID: "60",
            CompanyName: "Repair Solutions",
            Qty: 1,
            TotalPrice: "1500"
          }
        ],
      
        "FiveStar Automotives": [
          {
            SparePartID: "51",
            Name: "Brakes",
            Price: "234",
            VendorID: "70",
            CompanyName: "FiveStar Automotives",
            Qty: 1,
            TotalPrice: "234"
          },
          {
            SparePartID: "53",
            Name: "Clutch",
            Price: "999",
            VendorID: "70",
            CompanyName: "FiveStar Automotives",
            Qty: 1,
            TotalPrice: "999"
          },
          {
            SparePartID: "55",
            Name: "LED",
            Price: "288",
            VendorID: "70",
            CompanyName: "FiveStar Automotives",
            Qty: 1,
            TotalPrice: "288"
          }
        ]
      };
      
      class App extends React.Component {
        state = {
          records: RECORDS
        };
      
        onChangeQty = (companyName, sid, e) => {
          const { records } = this.state;
      
          const newQty = e.target.value;
      
          this.setState({
            records: {
              ...records,
              [companyName]: records[companyName].map(product =>
                product.SparePartID === sid
                  ? {
                      ...product,
                      Qty: newQty,
                      TotalPrice: newQty * product.Price
                    }
                  : product
              )
            }
          });
        };
      
        render() {
          const { records } = this.state;
      
          return (
            <div className="App">
              {Object.keys(records).map((CompanyName, i) => (
                <div key={CompanyName}>
                  <h2>Supplier: {CompanyName}</h2>
                  {records[CompanyName].map((product, i) => (
                    <tr>
                      <td>
                        <h4> {product["SparePartID"]} </h4>
                      </td>
      
                      <td>
                        <h4>{product["Name"]} </h4>
                      </td>
      
                      <td>
                        <h4> {product["Price"]} </h4>
                      </td>
      
                      <td>
                        <input
                          type="number"
                          value={product["Qty"]}
                          min="1"
                          onChange={e =>
                            this.onChangeQty(CompanyName, product["SparePartID"], e)
                          }
                        />
                      </td>
      
                      <td> $ {product["TotalPrice"]}</td>
                    </tr>
                  ))}
                </div>
              ))}
            </div>
          );
        }
      }
      
      const rootElement = document.getElementById("root");
      ReactDOM.render(<App />, rootElement);
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

      【讨论】:

        猜你喜欢
        • 2023-01-03
        • 2019-09-23
        • 2021-05-14
        • 1970-01-01
        • 2019-04-11
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        相关资源
        最近更新 更多