【问题标题】:How to map using useState React如何使用 useState React 进行映射
【发布时间】:2020-03-02 03:36:25
【问题描述】:

我有一个输入字段,我想在其中输入一个数字;然后这个数字应该存储在指定键“mktratedelta”中的状态。

我正在使用映射来执行此操作。出于某种原因,我无法在输入字段中输入。这是正确的方法吗?如何解决这个问题?

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


【问题讨论】:

  • 请粘贴完整的组件代码
  • 如果你想改变marketEstimateDataBCAssets,你需要调用setmarketEstimateData而不是改变它。
  • 另外marketEstimateDataBCAssets 是一个数组而不是一个对象。 Object.keys(marketEstimateDataBCAssets) 不应按预期工作。你会得到这样的数组["0", "1"]
  • @GangadharGandi 我正在调用 setmarketEstimateData 但我仍然无法在输入字段中输入
  • @CliveCharles 直接使用地图。如marketEstimateDataBCAssets.map(asset =&gt; (&lt;div&gt;{asset.name}&lt;/div&gt;))

标签: javascript reactjs frontend


【解决方案1】:

这是一个如何将逻辑拆分为两个组件并呈现资产列表的示例

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

如果你对marketData数组中的属性名有影响,那么你应该考虑使用camelCase,所以

{
  id: 0,
  name: 'Lombard',
  prevgroupinputrate: 0.01,
  currgroupinputrate: 0.02,
  mktratedelta: 0.03,
  mktrateestimate: 0.04,
}

变成

{
  id: 0,
  name: 'Lombard',
  prevGroupInputrate: 0.01,
  currGroupInputrate: 0.02,
  mktRateDelta: 0.03,
  mktRateEstimate: 0.04,
}

【讨论】:

    【解决方案2】:

    类似的东西。

    
    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;
    
    
    

    【讨论】:

      【解决方案3】:

      代码存在一些问题。 1.你不能在数组上做Object.keysmarketEstimateDataBCAssets是你代码中的一个数组);

      1. 您不能直接将值分配给状态对象。

      您只需删除Object.keys即可解决第一个问题;

      对于第二个问题,只需创建一个函数,将数组键值与输入值一起传递。在函数中创建一个数组并更新索引对象的值,然后简单地将新数组数据传递给setmarketEstimateData

      所以代码将是:

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

      【讨论】:

      • 我试过了,但在这里我收到一条错误消息“TypeError: Cannot read property 'name' of undefined”
      • 感谢您的回答,但这段代码给了我“无法设置未定义的属性 'mktratedelta'”
      【解决方案4】:

      您正在直接更改state。不要这样做。试试这样的:

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

      这是一个快速的demo。感谢@Titus 指出问题。

      【讨论】:

      • 这将为marketEstimateDataBCAssets数组添加一个新值,你应该使用.map(..)之类的东西而不是传播。
      • @blueseal “
        {marketEstimateDataBCAssets[key].mktrateestimate}
        ”中的值没有改变,在控制台中我收到以下错误“未捕获(承诺)类型错误:每当我在输入字段中输入内容时,都无法读取未定义的属性“加入”
      • @CliveCharles 我忘记将字符串转换为浮点数parseFloat(e.target.value)。我更新了代码。 codesandbox.io/s/so-58716819-ru31i。我想你想改变input mktratedelta 而不是mktrateestimate
      • 首先谢谢你,我想做的是在“mktrateestimate”中显示“currgroupinputrate”和“mktratedelta”的添加我想从小处着手,所以我尝试在“ mktratedelta" 输入字段然后这个输入应该显示在 mktrateestimate 但我无法
      • 您可以在 SO 上创建另一个问题,我会回答。我认为这个问题与您目前面临的问题不同。 :)
      猜你喜欢
      • 2020-03-03
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      相关资源
      最近更新 更多