首页 > 解决方案 > 重命名作为 React 状态一部分的键值

问题描述

我有一个带有输入字段key的表单。value我希望用户能够编辑键值对。Value 只是编辑值,但 key 需要将 key 更新为他正在输入的内容。我让值更改工作,但我不确定如何编辑密钥,因为这需要更新、删除和跟踪更改的密钥。

所以可以说这是当前状态:

{"name":"Joe"}

现在用户想要在文本字段中将名字编辑为名字。

当他键入时,每次按键时状态将如下所示:

{"f":"Joe"}
{"fi":"Joe"}
{"fir":"Joe"}
{"firs":"Joe"}
{"first":"Joe"}
{"firstn":"Joe"}
etc

这是我的代码:

function KeyValuePair({ initialPair }) {
  const [pairs, setPairs] = React.useState(initialPair ? initialPair : {});
  const handleInputUpdate = e => {
    const { name, value, id } = e.target;
    if (name === "key") {
      // ??
    }
    if (name === "value") {
      setPairs({ ...pairs, [id]: value });
    }
  };
}

<Grid item lg={3}>
  <TextField
    name="key"
    label="Key"
    id={key}
    value={key}
    margin="normal"
    onChange={handleInputUpdate}
    fullWidth
  />
</Grid>
<Grid item lg={3}>
  <TextField
    name="value"
    label="Value"
    margin="normal"
    id={key}
    value={pairs[key]}
    onChange={handleInputUpdate}
    fullWidth
  />
</Grid>

更新

我让它像这样工作:

const handleInputUpdate = e => {
  const { name, value, id } = e.target;
  if (name === "key") {
    const keyValue = pairs[id];
    let oldState = pairs;
    delete oldState[id];
    setPairs({ ...oldState, [value]: keyValue });
  }
  if (name === "value") {
    setPairs({ ...pairs, [id]: value });
  }
};

但这在键入时会失去焦点,因为旧元素已被删除并呈现新键。需要保持专注,这样你才能继续打字。

标签: javascriptreactjsmaterial-ui

解决方案


由于您的键是可编辑的,因此您需要依赖另一个可以在键值对更改时依赖的属性 - 例如单独的 id 或它们在数组中的索引位置。

沿着数组路线,您的条目将如下所示:

const initialEntries = [
  { key: "myKey", value: "myValue" },
  { key: "myOtherKey", value: "myOtherValue" },
  { key: "otherOtherKey", value: "otherOtherValue" }
];

如果您映射您的条目,您可以使用索引:

 {entries.map((entry, index) => (
    <div>
      <span>{index}</span>
      <input
        name="key"
        onChange={ev => updateKey(index, ev)}
        value={entry.key}
      />
      <input
        nanme="value"
        onChange={ev => updateValue(index, ev)}
        value={entry.value}
      />
    </div>
  ))}

然后处理更新:

 const updateKey = (id, ev) => {
    const newKeyValue = ev.target.value;
    const updatedEntries = entries.map((entry, index) =>
      index === id ? { ...entry, key: newKeyValue } : entry
    );
    setEntries(updatedEntries);
  };
  const updateValue = (id, ev) => {
    const newValueValue = ev.target.value;
    const updatedEntries = entries.map((entry, index) =>
      index === id ? { ...entry, value: newValueValue } : entry
    );
    setEntries(updatedEntries);
  };

这是一个工作代码框,大致显示了您如何做到这一点:https ://codesandbox.io/s/sleepy-cherry-n0518


推荐阅读