【问题标题】:Mapping useState array into input fields将 useState 数组映射到输入字段
【发布时间】:2021-10-10 22:33:35
【问题描述】:

我正在尝试绘制状态中的值以制作动态输入列表。但是,我不太确定如何正确映射它。任何帮助将不胜感激,谢谢。

这是我得到的:

 import React, { useState } from "react";

const Values = () => {
  const [values, setValues] = useState([
    { name: "sean", income: 0, spending: 0, investment: 0 },
    { name: "bobby", income: 0, spending: 0, investment: 0 },
    { name: "katie", income: 0, spending: 0, investment: 0 },
    { name: "mary", income: 0, spending: 0, investment: 0 },
    { name: "elly", income: 0, spending: 0, investment: 0 },
  ]);

  const allIncome = "adding up all the values of income here";

  return (
    <form className="box">
      {values.map(() => (
        <div className="container">
          <div>{values.name}</div>
          <input
            type="number"
            value={values.income}
            onChange={(e) => setValues({ income: e.target.value })}
          />
          <input
            type="number"
            value={values.spending}
            onChange={(e) => setValues.apply({ spending: e.target.value })}
          />
          <input
            type="number"
            value={values.investment}
            onChange={(e) => setValues({ investment: e.target.value })}
          />
        </div>
      ))}
      <input type="submit" />
    </form>
  );
};

export default Values;

【问题讨论】:

  • 真的不太清楚你要做什么大哥

标签: javascript arrays reactjs react-hooks use-state


【解决方案1】:

对于这种情况,我建议在 onChange 回调中使用高阶函数来关闭 id 属性或索引(如果您不删除或排序记录),这样您就可以唯一地标识数组元素你想更新。从这里您可以使用典型的输入 namevalue 来应用更新。

例子:

const changeHandler = index => event => {
  const { name, value } = event.target;
  setValues(values => values.map((el, i) => index === i 
    ? {
        ...el,
        [name]: value,
      }
    : el,
  ));
};

映射数据时,您附加回调并传递当前索引。在每个输入上传递/设置 value 属性时,您应该引用当前的 value 元素,引用每个数据元素的嵌套属性。不要忘记为最外层的映射元素添加一个 React 键

<form className="box">
  {values.map((value, index) => ( // <-- current element value and index
    <div
      key={index} // <-- add React key
      className="container"
    >
      <div>{value.name}</div> // <-- reference from current value
      <input
        type="number"
        name="income" // <-- name matches state field
        value={value.income}
        onChange={changeHandler(index)} // <-- add callback, pass current index
      />
      <input
        type="number"
        name="spending"
        value={value.spending}
        onChange={changeHandler(index)}
      />
      <input
        type="number"
        name="investment"
        value={value.investment}
        onChange={changeHandler(index)}
      />
    </div>
  ))}
  <input type="submit" />
</form>

理想情况下,您的数据应该有一个专用的 GUID,例如 id 属性。这比使用索引更可取,因为索引不是数据的固有属性。原因是现在您可以删除、排序等... values 数组和 React 键是元素 React 的 id 可以优化重新渲染 UI。更深入的解释见Lists & Keys

使用 id 属性的更新程序:

const changeHandler = id => event => {
  const { name, value } = event.target;
  setValues(values => values.map((el) => el.id === id 
    ? {
        ...el,
        [name]: value,
      }
    : el,
  ));
};

...

<form className="box">
  {values.map((value) => ( // <-- current element value
    <div
      key={value.id} // <-- add React key
      className="container"
    >
      <div>{value.name}</div> // <-- reference from current value
      <input
        type="number"
        name="income"
        value={value.income}
        onChange={changeHandler(value.id)} // <-- add callback, pass current id
      />
      <input
        type="number"
        name="spending"
        value={value.spending}
        onChange={changeHandler(value.id)}
      />
      <input
        type="number"
        name="investment"
        value={value.investment}
        onChange={changeHandler(value.id)}
      />
    </div>
  ))}
  <input type="submit" />
</form>

【讨论】:

    猜你喜欢
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 2015-03-18
    • 1970-01-01
    • 2015-04-20
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多