我的 render
函数中有一个简单的表单,如下所示:
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
//How to access email and password here ?
}
我应该在 handleLogin: function() { ... }
中写什么来访问 Email
和 Password
字段?
onSubmit
而不是单击按钮 - 这样您还将处理通过按 Enter 提交表单的用户。
<input type=text>
中按 Enter 键时,将提交带有 <button>
的 <form>
或带有 type=submit
的 <input>
。如果您依赖于按钮的 onClick
,则用户必须单击该按钮或将其聚焦并按 Enter/空格键。使用 onSubmit
将启用这两个用例。当表单不支持 Enter 提交时,他们会感到崩溃。
有几种方法可以做到这一点:
1) 通过索引从表单元素数组中获取值
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target[0].value)
}
2)在html中使用name属性
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target.elements.username.value) // from elements property
console.log(event.target.username.value) // or directly
}
<input type="text" name="username"/>
3)使用参考
handleSubmit = (event) => {
console.log(this.inputNode.value)
}
<input type="text" name="username" ref={node => (this.inputNode = node)}/>
完整示例
class NameForm extends React.Component {
handleSubmit = (event) => {
event.preventDefault()
console.log(event.target[0].value)
console.log(event.target.elements.username.value)
console.log(event.target.username.value)
console.log(this.inputNode.value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
name="username"
ref={node => (this.inputNode = node)}
/>
</label>
<button type="submit">Submit</button>
</form>
)
}
}
使用输入上的 change
事件来更新组件的状态并在 handleLogin
中访问它:
handleEmailChange: function(e) {
this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>);
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
}
工作fiddle。
另外,阅读文档,有一整节专门用于处理表单:Forms
以前你也可以使用 React 的双向数据绑定助手 mixin 来实现相同的目的,但现在它已被弃用,取而代之的是设置值和更改处理程序(如上):
var ExampleForm = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {email: '', password: ''};
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
},
render: function() {
return (
<form>
<input type="text" valueLink={this.linkState('email')} />
<input type="password" valueLink={this.linkState('password')} />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
}
});
文档在这里:Two-way Binding Helpers。
valueLink
的功能,您的第一个示例应设置输入元素的 value
。没有它,React 术语中的值是 "uncontrolled"。 <input ... value={this.state.password}>
。
补充迈克尔·肖克的回答:
class MyForm extends React.Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
const data = new FormData(event.target);
console.log(data.get('email')); // reference by form input's `name` tag
fetch('/api/form-submit-url', {
method: 'POST',
body: data,
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="username">Enter username</label>
<input id="username" name="username" type="text" />
<label htmlFor="email">Enter your email</label>
<input id="email" name="email" type="email" />
<label htmlFor="birthdate">Enter your birth date</label>
<input id="birthdate" name="birthdate" type="text" />
<button>Send data!</button>
</form>
);
}
}
See this Medium article: How to Handle Forms with Just React
此方法仅在按下提交按钮时获取表单数据。更清洁的海事组织!
另一种方法是使用 ref
属性并使用 this.refs
引用值。这是一个简单的例子:
render: function() {
return (<form onSubmit={this.submitForm}>
<input ref="theInput" />
</form>);
},
submitForm: function(e) {
e.preventDefault();
alert(React.findDOMNode(this.refs.theInput).value);
}
更多信息可以在 React 文档中找到:https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute
由于 How do I use radio buttons in React? 中描述的许多原因,这种方法并不总是最好的,但在一些简单的情况下它确实提供了一种有用的替代方法。
对于那些不想使用 ref 并使用 OnChange
事件重置状态的人,您可以只使用简单的 OnSubmit 句柄并循环通过 FormData
对象。
请注意,您不能直接访问 formData.entries()
,因为它是可迭代的,您必须对其进行循环。
这个例子使用了 React Hooks:
const LoginPage = () => {
const handleSubmit = (event) => {
const formData = new FormData(event.currentTarget);
event.preventDefault();
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="username" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</div>
);
};
如果您使用的是 TypeScript:
export const LoginPage: React.FC<{}> = () => {
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (event) => {
const formData = new FormData(event.currentTarget);
event.preventDefault();
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="username" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</div>
);
};
new FormData(event.target)
为我提供 {}
无需使用 refs,您可以使用 event 访问
function handleSubmit(e) {
e.preventDefault()
const {username, password } = e.target.elements
console.log({username: username.value, password: password.value })
}
<form onSubmit={handleSubmit}>
<input type="text" id="username"/>
<input type="text" id="password"/>
<input type="submit" value="Login" />
</form>
处理 refs 的简单方法:
类 UserInfo 扩展 React.Component { 构造函数(道具) { 超级(道具); this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(e) { e.preventDefault();常量 formData = {}; for (this.refs 中的常量字段) { formData[field] = this.refs[field].value; } console.log('-->', formData); } render() { return (
map()
后面使用 Object.keys()
,如下所示:Object.keys(this.refs).map(field => formData[field] = this.refs[field].value)
<input type="text" ref={(input) => { this.textInput = input; }} />
您可以将按钮上的 onClick
事件处理程序切换为表单上的 onSubmit
处理程序:
render : function() {
return (
<form onSubmit={this.handleLogin}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
然后,您可以使用 FormData
解析表单(如果需要,还可以从其条目构造一个 JSON 对象)。
handleLogin: function(e) {
const formData = new FormData(e.target)
const user = {}
e.preventDefault()
for (let entry of formData.entries()) {
user[entry[0]] = entry[1]
}
// Do what you will with the user object here
}
如果您的所有输入/文本区域都有名称,那么您可以从 event.target 中过滤所有内容:
onSubmit(event){
const fields = Array.prototype.slice.call(event.target)
.filter(el => el.name)
.reduce((form, el) => ({
...form,
[el.name]: el.value,
}), {})
}
完全不受控制的形式😊没有 onChange 方法、值、defaultValue ......
我建议采用以下方法:
import {Autobind} from 'es-decorators';
export class Form extends Component {
@Autobind
handleChange(e) {
this.setState({[e.target.name]: e.target.value});
}
@Autobind
add(e) {
e.preventDefault();
this.collection.add(this.state);
this.refs.form.reset();
}
shouldComponentUpdate() {
return false;
}
render() {
return (
<form onSubmit={this.add} ref="form">
<input type="text" name="desination" onChange={this.handleChange}/>
<input type="date" name="startDate" onChange={this.handleChange}/>
<input type="date" name="endDate" onChange={this.handleChange}/>
<textarea name="description" onChange={this.handleChange}/>
<button type="submit">Add</button>
</form>
)
}
}
es6 destructing 的更清晰示例
class Form extends Component {
constructor(props) {
super(props);
this.state = {
login: null,
password: null,
email: null
}
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
let login = this.state.login;
let password = this.state.password;
// etc
}
render() {
return (
<form onSubmit={this.onSubmit.bind(this)}>
<input type="text" name="login" onChange={this.onChange.bind(this)} />
<input type="password" name="password" onChange={this.onChange.bind(this)} />
<input type="email" name="email" onChange={this.onChange.bind(this)} />
<button type="submit">Sign Up</button>
</form>
);
}
}
这是从表单获取数据的最短方法以及仅使用 FormData 避免 id 和 ref 的最佳方法
import React, { Component } from 'react'
class FormComponent extends Component {
formSubmit = (event) => {
event.preventDefault()
var data = new FormData(event.target)
let formObject = Object.fromEntries(data.entries())
console.log(formObject)
}
render() {
return (
<div>
<form onSubmit={this.formSubmit}>
<label>Name</label>
<input name="name" placeholder="name" />
<label>Email</label>
<input type="email" name="email" />
<input type="submit" />
</form>
</div>
)
}
}
export default FormComponent
此外,这也可以使用。
handleChange: function(state,e) {
this.setState({[state]: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
console.log("EMail: ", this.state.email);
console.log("Password: ", this.state.password);
}
像这样给你的输入参考
<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />
然后你可以像 soo 一样在你的 handleLogin 中访问它
handleLogin: function(e) {
e.preventDefault();
console.log(this.refs.email.value)
console.log(this.refs.password.value)
}
在 javascript 中的许多事件中,我们有 event
,它给出了一个对象,包括发生了什么事件以及值是什么等......
这也是我们在 ReactJs 中使用表单的方式......
因此,在您的代码中,您将状态设置为新值……如下所示:
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
}
handleLogin(e) {
e.preventDefault();
for (const field in this.refs) {
this.setState({this.refs[field]: this.refs[field].value});
}
}
render() {
return (
<div>
<form onSubmit={this.handleLogin}>
<input ref="email" type="text" name="email" placeholder="Email" />
<input ref="password" type="password" name="password" placeholder="Password" />
<button type="button">Login</button>
</form>
</div>
);
}
}
export default UserInfo;
这也是 React v.16 中的表单示例,作为您将来创建的表单的参考:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
我使用 React 组件状态这样使用:
<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />
handleChange(e){
this.setState({[e.target.name]: e.target.value})
}`
onChange(event){
console.log(event.target.value);
}
handleSubmit(event){
event.preventDefault();
const formData = {};
for (const data in this.refs) {
formData[data] = this.refs[data].value;
}
console.log(formData);
}
<form onSubmit={this.handleSubmit.bind(this)}>
<input type="text" ref="username" onChange={this.onChange} className="form-control"/>
<input type="text" ref="password" onChange={this.onChange} className="form-control"/>
<button type="submit" className="btn-danger btn-sm">Search</button>
</form>
这可能有助于 Meteor (v1.3) 用户:
render: function() {
return (
<form onSubmit={this.submitForm.bind(this)}>
<input type="text" ref="email" placeholder="Email" />
<input type="password" ref="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
submitForm: function(e) {
e.preventDefault();
console.log( this.refs.email.value );
console.log( this.refs.password.value );
}
改善用户体验;当用户单击提交按钮时,您可以尝试让表单首先显示发送消息。一旦我们收到来自服务器的响应,它就可以相应地更新消息。我们通过链接状态在 React 中实现了这一点。请参阅 codepen 或下面的片段:
以下方法进行第一次状态更改:
handleSubmit(e) {
e.preventDefault();
this.setState({ message: 'Sending...' }, this.sendFormData);
}
一旦 React 在屏幕上显示上述发送消息,它就会调用将表单数据发送到服务器的方法:this.sendFormData()。为简单起见,我添加了一个 setTimeout 来模仿这一点。
sendFormData() {
var formData = {
Title: this.refs.Title.value,
Author: this.refs.Author.value,
Genre: this.refs.Genre.value,
YearReleased: this.refs.YearReleased.value};
setTimeout(() => {
console.log(formData);
this.setState({ message: 'data sent!' });
}, 3000);
}
在 React 中,方法 this.setState() 渲染一个具有新属性的组件。因此,您还可以在表单组件的 render() 方法中添加一些逻辑,这些逻辑将根据我们从服务器获得的响应类型而有所不同。例如:
render() {
if (this.state.responseType) {
var classString = 'alert alert-' + this.state.type;
var status = <div id="status" className={classString} ref="status">
{this.state.message}
</div>;
}
return ( ...
这是动态添加字段的示例。这里表单数据将使用 React useState 钩子通过输入名称键存储。
导入 React, { useState } from 'react' function AuthForm({ firebase }) { const [formData, setFormData] = useState({}); // 关于表单提交 const onFormSubmit = (event) => { event.preventDefault(); console.log('data', formData) // 在这里提交 }; // 获取数据 const getData = (key) => { return formData.hasOwnProperty(key) ? formData[key] : ''; }; // 设置数据 const setData = (key, value) => { return setFormData({ ...formData, [key]: value }); }; console.log('firebase', firebase) return (
如果元素名称多次出现,则必须使用 forEach()。
html
<input type="checkbox" name="delete" id="flizzit" />
<input type="checkbox" name="delete" id="floo" />
<input type="checkbox" name="delete" id="flum" />
<input type="submit" value="Save" onClick={evt => saveAction(evt)}></input>
js
const submitAction = (evt) => {
evt.preventDefault();
const dels = evt.target.parentElement.delete;
const deleted = [];
dels.forEach((d) => { if (d.checked) deleted.push(d.id); });
window.alert(deleted.length);
};
请注意,这种情况下的 dels 是 RadioNodeList,而不是数组,也不是 Iterable。 forEach() 是列表类的内置方法。您将无法在此处使用 map() 或 reduce()。
<form onSubmit={handleLogin}>
<input type="text" name="email" placeholder="Email" />
<input type="text" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
const handleLogin = (event) => {
event.preventDefault();
console.log(event.target[0].value)
console.log(event.target[1].value)
}
我想这也是你需要的答案。另外,这里我添加了所需的属性。每个输入组件的 onChange 属性都是函数。您需要在那里添加自己的逻辑。
handleEmailChange: function(e) {
this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
formSubmit : async function(e) {
e.preventDefault();
// Form submit Logic
},
render : function() {
return (
<form onSubmit={(e) => this.formSubmit(e)}>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} required />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} required />
<button type="button">Login</button>
</form>);
},
handleLogin: function() {
//Login Function
}
这将是最简单的方法
const formValidator = (form) => {
let returnData = {}
console.log(form.length);
for (let i = 0; i < form.length; i++) {
const data = form[i]
if (data.name != null && data.name != "") {
returnData[data.name] = data.value;
}
}
return returnData
}
简单的形式
<form onSubmit={(e) => {
e.preventDefault()
let data = formValidator(e.currentTarget)
}}>
<RoundTextFiled name='app-id' style={{ marginTop: '10px', borderRadius: '20px' }} label="App id" fullWidth required />
<RoundTextFiled name='api-hash' style={{ marginTop: '5px' }} label="Api hash" fullWidth required />
<RoundTextFiled name='channel-id' style={{ marginTop: '5px' }} label="Channel id" fullWidth required />
<Button type='submit' variant="contained" fullWidth style={{ padding: '10px', marginTop: '5px', borderRadius: '10px' }}>Login</Button>
</form>
我知道这个问题很老,但我想到的最简单的解决方案是:
<form onSubmit={(e) => handleLogin(e)}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
您的手柄功能:
const handleLogin = (e) => {
e.preventDefault()
const data = {
email: e.target.elements.email.value,
password: e.target.elements.password.value
}
console.log('FormData: ', data)
}
当您单击登录按钮时,您将在控制台中看到以下格式的 FormData:FormData: {email: 'whatever you tiped here', password: 'also whatever you tiped here'}
。
e.target.elements.email.value
定位具有特定名称的元素,在您的情况下是电子邮件和密码。
在handleLogin
中的console.log
之后,您可以做一些验证逻辑和登录逻辑。
event
参数,那么通过getElementById
获取元素就是多余的。event.target.form.username.value
。这对我有用。