![](/img/trans.png)
[英]React JS : grandparent component's setState method doesn't update state of a grandchild input field onChange event click
[英]How to Update JSON Object's state for onChange event in REACT JS?
我的狀態為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分組,並且針對每個Item都有一個數量字段。 數量默認為1,因此TotalPrice與UnitPrice相同。
現在,我希望對Qty的任何特定輸入字段進行onChange,JSON 對象中相應的TotalPrice項目也應在myrecords []狀態下進行更新。 同樣, 數量也應在myrecords []狀態下進行更新。
PS: 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 }); }
首先改變這個
{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)進行操作。 只需在此函數onChange={(e) => this.onChangeQty
上傳遞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
});
}
警告:代碼未經測試。 請檢查並讓我知道 :)
您正在嘗試在this.state.myrecord
找到一個項目。 但是您應該在特定的公司中。 這是演示 。
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>
問題是this.state.myrecords
是一個對象,因此我們不能直接在其上使用find
。 另外,您還需要使用更新程序功能(有關更多詳細信息,請參閱doc) 。
您的問題的解決方案是:在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;
});
}
}
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.