0

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

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

但是我得到了关于循环循环对象值的 TypeError。循环这些值可能不是正确的方法,正如我通过登录控制台看到的 event.target 和 event.target.elements 实际上包含 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 句柄方法中循环遍历这些值。我无法通过 fetch 将表单数据发送到我的节点 + 快递服务器。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 发送它,它就可以工作。那么,有谁知道如何遍历表单元素或如何解决获取问题?谢谢 :))

4

3 回答 3

2

这不是你在 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
  });
}

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

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);
    }
  };
于 2020-04-03T09:02:48.933 回答
0

该错误似乎来自将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所示。您不必使用受控组件。

您可能不需要受控组件 - swyx 博客

于 2020-04-03T09:34:02.697 回答
0

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

表单上的 React 文档

于 2020-04-03T09:07:14.147 回答