反应形式:循环通过event.target来创建一个对象



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

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

但是我得到了关于循环循环对象值的TypeError。这可能不是循环这些值的正确方式,正如我在控制台event.target和event.target.element中看到的那样,它们实际上包含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的表单数据发送到我的节点+express服务器。req.body最终总是空的。我想这是因为我使用body解析器,并且我发送了一个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});
}

最后,当提交表单时,您需要使用该表单中的值。状态

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

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

在表单上反应文档

错误似乎来自于将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钩子表单所示,非受控表单具有性能改进和减少的重发器。您没有使用受控组件。

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

最新更新