React 形式:循环 event.target 来创建一个对象
React form: loop through event.target to create an object
我要提交一个相当长的表单,我想创建一个对象,其中包含输入的名称作为键,输入的值作为值。我尝试循环遍历 event.target
和 event.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);
}
};
您有没有使用受控组件的原因?您可以将输入值保留在状态中,并且在提交表单时,您只需使用状态中的值。
错误似乎来自将 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 所示。您没有使用受控组件。
我要提交一个相当长的表单,我想创建一个对象,其中包含输入的名称作为键,输入的值作为值。我尝试循环遍历 event.target
和 event.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);
}
};
您有没有使用受控组件的原因?您可以将输入值保留在状态中,并且在提交表单时,您只需使用状态中的值。
错误似乎来自将 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 所示。您没有使用受控组件。