- 通过onXXX属性指定事件处理函数,即小驼峰命名法。react使用的是自定义事件,而不是使用的原生dom事件。react中的事件是通过事件委托方式处理。
- react在事件处理函数中也可以通过event.target得到事件发生时的真实DOM元素。
受控组件:
- 主要指的就是跟表单有关系。获取表单的value值和React里的state结合起来。
- 表单的输入项就叫做可控组件。而表单里的value值是通过组件里的state控制。
在HTML中,表单元素(如<input> <select> <textarea>)之类的表单元素通常自己维护state,并根据用户输入进行更新,而在React中,可变状态通常保存在组件的state属性中,并且只能通过setState()来更新。
我们可以把两者结合起来,使React的state称为“唯一数据源”,渲染表单的React组件还控制着用户输入过程中表单发生的操作。被React以这种方式控制取值的表单输入元素就叫做受控组件。
表单里的state指的就是它的value值的变化。(可变的状态指的就是value值的变化)
export default class App extends Component {
state={
userInput:"root"
}
render() {
return (
<div>
<p>
<label>用户名:</label><input type="text" value={this.state.userInput} onChange={this.changeUser}/>
{/*把默认的value值设置为state里的值,并给该元素绑定onChange或onInput事件,
当我修改input值的时候,那我定义的state里的userInput的值自动修改了,这就叫受控组件 */}
</p>
<p><button onClick={this.login}>提交按钮</button></p>
{/*点击按钮的时候,获区state的userInput值就是我们输入进去的值 */}
</div>
)
}
changeUser=(event)=>{
this.setState({userInput:event.target.value})
}
login=()=>{
alert(this.state.userInput)
}
}
- 受控组件:表单里的value值是组件state的初始值,通过onChange事件控制setState去修改input的value值,这时候value值就变为了我们输入过的值,再做提交事件时,直接获取state里面的被修改过的值就得到了input的值了。
- 为了实现代码复用,把onChange里的事件改写为箭头函数,并传参(传event和state里控制input默认value值的键名)
export default class kekong extends Component {
state={
userInput:"root",
pwdInput:"",
}
render() {
return (
<div>
<p>
<label for="a">用户名:</label>
<input
type="text"
value={this.state.userInput}
onChange={(event) => this.changeValue(event,"userInput")}
id="a"
/>{/*注意在onChange里写箭头函数时,必须传参event,
才可以在事件函数里用event */}
</p>
<p><button onClick={()=>this.tijiao("userInput")}>提交用户名</button></p>
<p>
<label for="a">密码:</label>
<input
type="password"
value={this.state.pwdInput}
onChange={(event) => this.changeValue(event,"pwdInput")}
id="a"/>
</p>
<p><button onClick={()=>this.tijiao("pwdInput")}>提交密码</button></p>
{/*注意:点击按钮,React先调用箭头函数 ,在执行里面的函数体*/}
</div>
)
}
changeValue=(event,stateName)=>{
this.setState({[stateName]:event.target.value})
}
tijiao=(uInp)=>{
alert(this.state[uInp])
}
}
高阶函数和函数柯里化
- 在获取表单数据时,推荐使用受控组件进行获取,但是每个表单项都需要一个处理函数将表单数据存储到state中,那有没有简化的方式呢?
- 使用高阶函数:
- 如果一个函数符合下面任何一个,该函数就是高阶函数:
-
- 若函数接收的参数是一个函数,那么该函数就可以称之为高阶函数。
-
-
若函数调用的返回值依然是一个函数,那么该函数就可以称之为高阶函数。
-
函数的柯里化
- 通过函数调用继续返回函数的方式,实现多次接受参数最后统一处理的函数,高阶函数就是柯里化的一种表现。
- 函数的柯里化:函数的返回值又是一个函数,这个函数又接收参数,最后统一的去处理程序
非受控组件:(尽量还是用受控组件)
- 受控组件的替代品
- 有时使用受控组件会很麻烦,因为你需要为数据变化的每种方式都编写号事件处理函数,并通过一个
React组件传递所有的输入state。当你将之前的代码库转换为React或将React应用程序与非React库集成时,这可能会令人厌烦。在这些情况下,你可能希望使用非受控组件,这是实现输入表单的另一种方式。 - 简单来说,就是不需要使用
state去控制和获取input的value值了,而是直接通过Ref获取。 - 在大多数情况下,我们推荐使用受控组件处理表单数据。在一个受控组件中,表单数据是由
React组件来管理的。另一种替代方案是使用非受控组件,这时表单数据将交由DOM节点来处理。 - 要编写一个非受控组件,而不是为了每个状态更新都编写数据处理函数,你可以使用
ref来从DOM节点中获取表单数据。 - 因为非受控组件将真实数据存储在
DOM节点中,所以在使用非受控组件时,有时候反而更容易同时集成React和非React代码。如果你不在意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件
默认值:
- 在React渲染生命周期时,表单元素上的
value将会覆盖DOM,节点中的值,在非受控组件中,你经常希望React能赋予组件一个初始值,但是不去控制后续的更新。在这种情况下,defaultValue属性,而不是value。 - 同样:
<input type="checkbox">和<input type="radio">支持defaultChecked,<select>和<textarea>支持defaultValue。
在非受控组件里,使用value值不生效了,使用defaultValue属性。
受控组件通过组件的状态来获取和修改input的值,而非受控组件直接通过ref来获取input的值。