React 形式:循环 event.target 来创建一个对象

React form: loop through event.target to create an object

我要提交一个相当长的表单,我想创建一个对象,其中包含输入的名称作为键,输入的值作为值。我尝试循环遍历 event.targetevent.target.elements,如下所示:

handleModify(event) {
    let tempPlayer = {}
    Object.entries(event.target.elements).forEach(([name, input]) => {
        tempPlayer[name] = input;
    });
}

但是我得到了关于循环对象值的类型错误。这可能不是循环这些值的正确方法,正如我通过登录控制台 event.target 和 event.target 看到的那样。元素实际上包含 html 表单元素。我不知道如何获取表单数据。我的表单如下所示:

<form onSubmit={e=> props.onSubmit(e)}>
  <label htmlFor="name">
    Name:
    <input type="text" name="name" placeholder="Estelle Nze Minko" />
  </label>
  <label htmlFor="poste">
    Poste:
    <input type="text" name="poste" placeholder="Back" />
  </label>
  <label htmlFor="number">
    Number:
    <input type="number" min="0" max="100" step="1" name="number" placeholder="27" />
  </label>
  <label htmlFor="height">
    Height (m):
    <input type="number" min="1.00" max="2.34" step="0.01" name="height" placeholder="1.78" />
  </label>
  <label htmlFor="selects">
    Number of selects:
    <input type="number" min="0" max="300" step="1" name="selects" placeholder="88" />
  </label>
  <button type="submit">Add</button>
</form>

我之所以使用这种方法,是因为这是我在服务器端通过获取表单数据并循环 req.body 条目来实现的方法。但是现在我已经将 ejs 模板更改为 React,我无法发送表单数据。这就是为什么我试图直接在 React handle 方法中循环遍历这些值。我无法将带有 fetch 的表单数据发送到我的 node + express 服务器。 req.body 总是以空结束。我认为这是因为我正在使用 body-parser 并且我正在发送一个 new FormData()(不支持?)这样:

handleModify(event) {
    event.preventDefault();
    fetch(`/players/modify/${this.props.match.params.id}/confirm`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        mode: "cors",
        body: JSON.stringify(new FormData(event.target))
    });
}

但是,如果我先创建对象然后使用 fetch 发送它,它就可以工作。那么,有谁知道如何循环遍历表单元素或如何解决获取问题?谢谢:))

这不是你在 ReactJS 中应该做的。这是处理表单的好教程:https://reactjs.org/docs/forms.html

基本上您需要为每个输入设置一个值并处理它们各自的 onChange 回调:

例如

    <input type="text" name="name" value={this.state.name} onChange={onNameChange} placeholder="Estelle Nze Minko" />

然后在你的组件中你有一个方法 onNameChange 将新值保存到一个状态,例如:

onNameChange(event) {
  const name = event.target.value;
  this.setState(s => {...s, name});
}

最后,当提交表单时,您需要使用 this.state

中的值
handleSubmit(e) {
  e.preventDefault(); // prevent page reload
  const {name} = this.state;
  const data = JSON.stringify({name});
  fetch(`/players/modify/${this.props.match.params.id}/confirm`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    mode: "cors",
    body: data
  });
}

这只是一个例子,我建议你先阅读我给你的link

LE:使用不受控制的组件:

https://codesandbox.io/s/dark-framework-k2zkj 这里有一个我为非受控组件创建的示例。

基本上您可以在 onSubmit 函数中执行此操作:

  onSubmit(event) {
    event.preventDefault();
    const tempPlayer = new FormData(event.target);
    for (let [key, value] of tempPlayer.entries()) {
      console.log(key, value);
    }
  };

您有没有使用受控组件的原因?您可以将输入值保留在状态中,并且在提交表单时,您只需使用状态中的值。

React Docs on Forms

错误似乎来自将 input 本身存储为值,您可能最终在某处对其执行了操作。相反,您可以存储输入的名称和值:

tempPlayer[input.name] = input.value;

演示:

const root = document.getElementById("root");

const { render } = ReactDOM;

function App() {
  const handleSubmit = (event) => {
    event.preventDefault();
    let tempPlayer = {}
    Object.entries(event.target.elements).forEach(([name, input]) => {
        if(input.type != 'submit') {
          tempPlayer[input.name] = input.value;
        }
    });
    console.log(tempPlayer)
  }
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">
        Name:
        <input type="text" name="name" placeholder="Estelle Nze Minko" />
      </label>
      <label htmlFor="poste">
        Poste:
        <input type="text" name="poste" placeholder="Back" />
      </label>
      <label htmlFor="number">
        Number:
        <input
          type="number"
          min="0"
          max="100"
          step="1"
          name="number"
          placeholder="27"
        />
      </label>
      <label htmlFor="height">
        Height (m):
        <input
          type="number"
          min="1.00"
          max="2.34"
          step="0.01"
          name="height"
          placeholder="1.78"
        />
      </label>
      <label htmlFor="selects">
        Number of selects:
        <input
          type="number"
          min="0"
          max="300"
          step="1"
          name="selects"
          placeholder="88"
        />
      </label>
      <button type="submit">Add</button>
    </form>
  );
}

render(<App />, root);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

PS:众所周知,不受控制的表单可以提高性能并减少重新呈现,如 React hook form 所示。您没有使用受控组件。

You may not need Controlled Components - swyx Blog