上节课我们学习了非受控组件,当然,有非受控,那肯定就有受控,这节课,我们就来学习一下什么叫做受控组件
回顾
在学习受控组件之前,我们来对上节课做一个简单的回顾
form
表单可以用onSubmit
事件来代替给提交按钮加onClick
事件form
表单的onSubmit
事件的回调方法中可以通过event
来禁用默认提交事件- 禁用了
form
表单的默认提交事件后可以通过ajax
来完成与后台的交互 - 现用现取则是非受控
以上便是上节课我们所学内容,接下来我们来开始新的内容的学习
受控组件
上节课我们说了现用现取叫非受控组件,可能大家不理解,这种现用现取这不是很正常的逻辑吗?难道还有什么是提前取好的,等着你来用还是说有其他的吗?
那我们来看看呗:
class Login extends React.Component { notify = e => {e.preventDefault();} render() { return ( <form onSubmit={this.notify}> Username: <input type="text" name="username" /> Password: <input type="password" name="password" /> <button>Submit</button> </form> ); } } ReactDOM.render(<Login />, document.getElementById("test"));
我们先看看代码,几乎和上节课是一样的代码,但是input
标签没有了ref
,既然没有了ref
那么notify
方法中也不能像上节课那样取值了。那么我们接下来该怎么处理?
我不知道大家还记不记得有个原生的方法叫onchange
,只要是输入类的DOM
都可以绑定onchange
事件。从字面上看大家也能明白,只要输入值有变化就会触发事件。那么在react
中肯定有一个onChange
与之对应啊。那我们先测试一下onChange
:
class Login extends React.Component { notify = e => {...} change = () => {console.log("@");}; render() { return ( <form onSubmit={this.notify}> Username: <input onChange={this.change} type="text" name="username" /> Password: <input type="password" name="password" /> <button>Submit</button> </form> ); } }
我们先给用户名的input
标签添加了onChange
事件。那么我们想一下,只要我们在用户名的input
栏里面是不是只要一输入或者一删除就会在控制台中打印出@
?那我们来看一下效果:
我输入了 7 个数字,然后在控制台中就打印了 7 次@
。我们目前是随着我们的输入,我们指定的回调方法就不断呗调用,那我们能不能随着输入就拿到输入的值呢?当然是可以的。
我们来分析一下:
- 是不是给
input
绑定的onChange
? - 是不是要拿到这个
input
的值?
那么直接借助event.target
就可以了啊,我们吧代码改一下:
class Login extends React.Component { notify = e => {...}; change = e => {console.log(e.target.value);}; render() { return ( <form onSubmit={this.notify}> Username: <input onChange={this.change} type="text" name="username" /> Password: <input type="password" name="password" /> <button>Submit</button> </form> ); } }
我们在change
方法中直接通过event
来获取到了input
这个DOM
节点的值,那么我们看看打印出来是不是如我们预期一样:
如我们所见,我们在input
栏只要有变化,那么控制台就会打印出当前一次变化之后的值。
那么我们现在拿到值了。我们怎么用啊?我光拿到了不行啊。那我们怎么办呢?我们可以存到state
里面啊。那我们把代码这么一改:
class Login extends React.Component { notify = e => {...}; change = e => {this.setState({ username: e.target.value });}; render() { return ( <form onSubmit={this.notify}> Username: <input onChange={this.change} type="text" name="username" /> Password: <input type="password" name="password" /> <button>Submit</button> </form> ); } }
这样的话我每修改一下用户名的input
栏,是不是都会把input DOM
节点的值哇偶维护进了state
里面?可能有人要说了,我怎么就知道有没有维护到state
里呢?那我们来看一下呗:
我们在还没有输入任何值的时候,我们看一下啊,为什么没有state
?因为我们根本没有在代码里来做初始化。那么我们输入一下试试:
在我们的react
的开发工具中可以很直观得看到我们的state
拿到值了。但是这么做其实是不规范的。连初始化都没做就直接往里面放东西这种做法很明显不规范。那我们就初始化一下呗:
class Login extends React.Component { state = { username: "", password: "" } notify = e => {...} change = e => {...}; render() {return ...} }
所以说这一步我们最好在使用前来初始化一下。那么同理给password
的input
也同样加一个onChange
,并把输入的内容存放在state
中这一步我们是不是已经去到了输入的值了?但是我们用了吗?是不是我们只是取到了并且存储到了state
里了但是我们其实并没有拿来用。那么form
表单的onSubmit
事件的回调就好写了啊:
class Login extends React.Component { state = { username: "", password: "" } notify = e => { e.preventDefault(); const { username, password } = this.state; alert(`{username}: {password}`); } change = e => { this.setState({ username: e.target.value }); }; change1 = e => { this.setState({ password: e.target.value }); }; render() { return ( <form onSubmit={this.notify}> Username: <input onChange={this.change} type="text" name="username" /> Password: <input onChange={this.change1} type="password" name="password" /> <button>Submit</button> </form> ); } }
我们来看一下完整代码,初始化state
,render
方法中返回一个form
表单,form
表单绑定onSubmit
事件,该事件的回调方法是notify
方法。input
标签利用onChange
事件将输入的值存入state
,当点击提交按钮时触发form
表单的onSubmit
事件的回调方法,该方法用参数e
接收event
,并且用preventDefault
方法来禁止默认提交事件,然后从state
拿到username
和password
解构赋值,然后再弹窗展示出来。那么我们来看看具体是什么效果:
图中可以很直观德看出我们输入用户名和密码之后,点击提交按钮成功展示了相关信息,而且state
中也存储了我们输入的值。
所以说我们得出了这么一个结论。上面这种所有输入类的DOM
随着输入就可以将输入的值存入state
,等需要使用时直接从state
中取出来就属于受控组件。
所以我们对比非受控组件,差异就太明显了。因为非受控组件不经过state
啊,现用现取,在我们的案例中通过refs
去取,而受控组件则是在输入过程中就已经在取值并且维护到了state
中了。
那有人要问了,那我以后开发的时候是写受控组件还是非受控组件啊?其实我们是建议写受控组件的。我们在受控组件中是不是一个ref
都没用啊?官方给的建议就是尽量减少ref
的使用。那么我们受控组件的优势就出来了。
总结
- 受控组件在输入过程中就开始取值
- 受控组件把输入的值维护到
state
中 - 受控组件可以减少
ref
的使用
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/controled_component/