简体   繁体   中英

How to map using useState React

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);

  1. you can't Directly assign values to the state object.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM