我的状态为 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"
}
]
}
}
现在,Im在react js中显示此记录的方式是,所有项目都按行显示并按其 CompanyNames 分组,并且每个项目都有一个“数量”输入字段。 默认数量为1 ,因此TotalPrice与UnitPrice相同。
现在,我希望数量的任何特定输入字段的onChange,JSON Object 中相应的 TotalPrice 项目也应在 myrecords [] 状态。同样,数量也应在 myrecords []状态下得到更新。
P.S: myrecords [] 包含JSON 对象,而不是数组。
这是我的用于显示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
});
}
答案 0 :(得分:1)
首先更改此
{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
});
}
如果您不喜欢基于Change的索引,也可以按照以下方式(基于SID)进行操作。只需在此功能CompanyName,sid,e)
上传递onChange={(e) => 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
});
}
警告:代码未经测试。请检查并让我知道:)
答案 1 :(得分:1)
您正在尝试在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>
答案 2 :(得分:1)
问题是this.state.myrecords
是一个对象,因此我们不能直接在其上使用find
。另外,您需要使用here。
您的问题的解决方案是:在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;
});
}
}
};
}