Forms are one of the few HTML elements that are interactive by default.
表单是默认情况下可交互的少数HTML元素之一。
They were designed to allow the user to interact with a page.
它们旨在允许用户与页面进行交互。
Common uses of forms?
表格的常见用途?
- Search 搜索
- Contact forms 联络表格
- Shopping carts checkout 购物车结帐
- Login and registration 登录和注册
- and more! 和更多!
Using React we can make our forms much more interactive and less static.
使用React,我们可以使我们的表单更具交互性,并减少静态性。
There are two main ways of handling forms in React, which differ on a fundamental level: how data is managed.
在React中有两种主要的表单处理方式,它们在根本上有所不同:数据的管理方式。
if the data is handled by the DOM, we call them uncontrolled components
如果数据是由DOM处理的,我们称它们为不受控制的组件
if the data is handled by the components we call them controlled components
如果数据是由组件处理的,我们称它们为受控组件
As you can imagine, controlled components is what you will use most of the time. The component state is the single source of truth, rather than the DOM. But sometimes you are forced to use uncontroller components, for example when using some form fields that are inherently uncontrolled because of their behavior, like the <input type="file">
field.
您可以想象,大多数时候将使用受控组件。 组件状态是事实的唯一来源,而不是DOM。 但是有时您会被迫使用非控件组件,例如,当使用某些因其行为而固有不受控制的表单字段时,例如<input type="file">
字段。
When an element state changes in a form field managed by a component, we track it using the onChange
attribute.
当元素状态在由组件管理的表单字段中更改时,我们使用onChange
属性对其进行跟踪。
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
}
handleChange(event) {}
render() {
return (
<form>
Username:
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
</form>
)
}
}
With class components, in order to set the new state, we must bind this
to the handleChange
method, otherwise this
is not accessible from within that method:
随着类组件,以便设置新的状态,我们必须绑定this
到handleChange
方法,否则this
是不是从方法中访问:
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({ username: event.target.value })
}
render() {
return (
<form>
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
</form>
)
}
}
Similarly, we use the onSubmit
attribute on the form to call the handleSubmit
method when the form is submitted:
类似地,提交表单时,我们在表单上使用onSubmit
属性来调用handleSubmit
方法:
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ username: event.target.value })
}
handleSubmit(event) {
alert(this.state.username)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
<input type="submit" value="Submit" />
</form>
)
}
}
Using hooks it’s all much simpler:
使用钩子要简单得多:
const Form = props => {
const [username, setUsername] = useState()
const handleChangeUsername = e => {
setUsername(e.target.value)
}
const handleSubmit = event => {
alert(username)
event.preventDefault()
}
render() {
return (
<form onSubmit={handleSubmit}>
Username:
<input
type="text"
value={username}
onChange={handleChangeUsername}
/>
</form>
)
}
}
Validation in a form can be handled in the handleChange
method: you have access to the old value of the state, and the new one. You can check the new value and if not valid reject the updated value (and communicate it in some way to the user).
可以通过handleChange
方法处理表单中的handleChange
:您可以访问状态的旧值和状态的新值。 您可以检查新值,如果无效,则拒绝更新后的值(并将其以某种方式传达给用户)。
HTML Forms are inconsistent. They have a long history, and it shows. React however makes things more consistent for us, and you can get (and update) fields using its value
attribute.
HTML表单不一致。 他们有悠久的历史,这表明。 但是,React使事情对我们而言更加一致,您可以使用其value
属性获取(和更新)字段。
Here’s a textarea
, for example:
例如,这是一个textarea
:
<textarea value={this.state.address} onChange={this.handleChange} />
The same goes for the select
tag:
select
标记也是如此:
<select value="{this.state.age}" onChange="{this.handleChange}">
<option value="teen">Less than 18</option>
<option value="adult">18+</option>
</select>
Previously we mentioned the <input type="file">
field. That works a bit differently.
先前我们提到了<input type="file">
字段。 这有点不同。
In this case you need to get a reference to the field by assigning the ref
attribute to a property defined in the constructor with React.createRef()
, and use that to get the value of it in the submit handler:
在这种情况下,您需要通过将ref
属性分配给使用React.createRef()
在构造函数中定义的属性来获取对该字段的ref
,并使用该属性在提交处理程序中获取其值:
class FileInput extends React.Component {
constructor(props) {
super(props)
this.curriculum = React.createRef()
this.handleSubmit = this.handleSubmit.bind(this)
}
handleSubmit(event) {
alert(this.curriculum.current.files[0].name)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="file" ref={this.curriculum} />
<input type="submit" value="Submit" />
</form>
)
}
}
This is the uncontrolled components way. The state is stored in the DOM rather than in the component state (notice we used this.curriculum
to access the uploaded file, and have not touched the state
.
这是不受控制的组件方式。 状态存储在DOM中,而不是组件状态中(注意,我们使用this.curriculum
来访问上传的文件,并且没有接触过state
。
I know what you’re thinking - beyond those basics, there must be a library that simplifies all this form handling stuff and automates validation, error handling and more, right? There is a great one, Formik.
我知道您在想什么-除了这些基础知识之外,还必须有一个库可以简化所有表单处理工作,并自动执行验证,错误处理等等,对吗? 有一个伟大的, Formik 。