I have an input field where I would like to enter a number; this number then should be stored in the specified key "mktratedelta" in the state.
I am doing this with mapping. For some reason, I am not able to type in the input field. Is this the right approach and how to fix this issue?
const [marketEstimateDataBCAssets, setmarketEstimateData] = useState([
{
name: "Lombard",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.03,
mktrateestimate: 0.04
},
{
name: "Other Secured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.033,
mktrateestimate: 0.04
},
{
name: "Unsecured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.0333,
mktrateestimate: 0.04
}
]);
{Object.keys(marketEstimateDataBCAssets).map(function(key) {
return (
<Segment>
<div> {marketEstimateDataBCAssets[key].name}</div>
<div> {marketEstimateDataBCAssets[key].prevgroupinputrate}</div>
<div> {marketEstimateDataBCAssets[key].currgroupinputrate}</div>
<input
value={marketEstimateDataBCAssets[key].mktratedelta}
onChange={e =>
(marketEstimateDataBCAssets[key].mktratedelta = e.target.value)
}
/>
<div> {marketEstimateDataBCAssets[key].mktrateestimate}</div>
</Segment>
);
Here is an example of how to split up the logic into two components and render out a list of assets
function myAwesomeComponent() {
const [marketData, setMarketData] = useState([
{
id: 0,
name: 'Lombard',
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.03,
mktrateestimate: 0.04,
},
{
id: 1,
name: 'Other Secured',
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.033,
mktrateestimate: 0.04,
},
{
id: 2,
name: 'Unsecured',
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.0333,
mktrateestimate: 0.04,
},
]);
const onChange = (asset) => (event) => {
setMarketData((oldMarketData) => {
const index = oldMarketData.indexOf(asset);
const oldAsset = oldMarketData[index];
const newMarketData = [...oldMarketData];
newMarketData[index] = {
...oldAsset,
mktratedelta: event.target.value,
};
return newMarketData;
});
};
return (
<>
{marketData.map((asset) => (
<Asset asset={asset} onChange={onChange} />
))}
</>
);
}
const Asset = ({ asset, onChange }) => (
<Segment key={asset.id}>
<div> {asset.name}</div>
<div> {asset.prevgroupinputrate}</div>
<div> {asset.currgroupinputrate}</div>
<input value={asset.mktratedelta} onChange={onChange(asset)} />
<div> {asset.mktrateestimate}</div>
</Segment>
);
If you have influence on the property names from the marketData array, then you should consider using camelCase, so
{
id: 0,
name: 'Lombard',
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.03,
mktrateestimate: 0.04,
}
becomes
{
id: 0,
name: 'Lombard',
prevGroupInputrate: 0.01,
currGroupInputrate: 0.02,
mktRateDelta: 0.03,
mktRateEstimate: 0.04,
}
You are directly changing the state
. Don't do this. Try something like this:
return (
<>
{marketEstimateDataBCAssets.map((item, key) => (
<div>
<div> {item.name}</div>
<div> {item.prevgroupinputrate}</div>
<div> {item.currgroupinputrate}</div>
<input
value={item.mktratedelta}
onChange={e => {
const newArr = marketEstimateDataBCAssets.map(el => {
if (el.name === item.name) {
return { ...el, mktratedelta: parseFloat(e.target.value) };
}
return el;
});
console.log(newArr);
return setmarketEstimateData([...newArr]);
}}
/>
<div> {item.mktrateestimate}</div>}
</div>
))}
</>
);
here is a quick demo . thanks to @Titus for pointing out the issue.
There are a few issues with the code. 1. you can't do Object.keys
on Arrays ( marketEstimateDataBCAssets
is an array in your code);
you can solve the first issue by simply removing Object.keys
;
for the second issue just create a function pass the array key value with the input value. In the function create an array with and update the value of the indexed object then simply pass the new array data to setmarketEstimateData
so the code will be:
const [marketEstimateDataBCAssets, setmarketEstimateData] = useState([
{
name: "Lombard",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.03,
mktrateestimate: 0.04
},
{
name: "Other Secured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.033,
mktrateestimate: 0.04
},
{
name: "Unsecured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.0333,
mktrateestimate: 0.04
}
]);
function updateValue(e, key) {
let data = setmarketEstimateData;
data[key].mktratedelta = e.target.value;
marketEstimateDataBCAssets.map(data);
}
{marketEstimateDataBCAssets.map(function(item,key) {
return (
<Segment>
<div> {item.name}</div>
<div> {item.prevgroupinputrate}</div>
<div> {item.currgroupinputrate}</div>
<input
value={item.mktratedelta}
onChange={e => updateValue(e, updateValue(e, key))}
/>
<div> {item.mktrateestimate}</div>
</Segment>
);
}
Something like this.
import React from 'react';
const Component = () => {
const [marketEstimateDataBCAssets, setmarketEstimateData] = useState([
{
name: "Lombard",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.03,
mktrateestimate: 0.04
},
{
name: "Other Secured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.033,
mktrateestimate: 0.04
},
{
name: "Unsecured",
prevgroupinputrate: 0.01,
currgroupinputrate: 0.02,
mktratedelta: 0.0333,
mktrateestimate: 0.04
}
]);
const preSetEstimateData = (value, itemId) => {
const item = marketEstimateDataBCAssets[itemId];
const newItem = {
...item,
mktrateestimate: value,
}
setmarketEstimateData([
...marketEstimateDataBCAssets.slice(0, itemId),
newItem,
...marketEstimateDataBCAssets.slice(itemId)
]);
};
return (
<div>
{
marketEstimateDataBCAssets.map((item, id) => {
return (
<Segment>
<div> {item.name}</div>
<div> {item.prevgroupinputrate}</div>
<div> {item.currgroupinputrate}</div>
<input
value={item.mktratedelta}
onChange={e => preSetEstimateData(e.target.value, id)}
/>
<div> {item.mktrateestimate}</div>
</Segment>
)
})
}
</div>
)
}
export default Component;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.