ref是reference的简写,它是一个引用,在react中,我们使用ref来操作DOM。
- 在react中,我们可以通过
e.target
来获取到一个事件对应的DOM。还可以通过ref来获取到元素对应的DOM. ref后边跟一个箭头函数,箭头函数会自动接收一个参数,这个参数名字可以随便定义,表示当前元素,this.input是一个引用,指向了input对应的DOM节点。
<input
id="inserArea"
className="input"
value={this.state.inputValue}
onChange={this.handleInputChange}
ref={(input) => {this.input = input}}
/>
handleInputChange(e){
// 通过e.target获取DOM节点
// const value = e.target.value;
// 通过ref获取DOM节点
const value = this.input.value;
this.setState(()=>({
inputValue:value
}))
}
实际上,我们尽量不要使用ref,也就是尽量不要直接操作DOM,但是有时候我们业务场景非常复杂的时候,比如动画,不可避免的用到一些DOM标签,这个时候就要用ref来获取DOM。
- 当ref与setState合用的时候,会出现一些坑,DOM的获取并不及时,原因是setState是异步的,如果需要在数据变化(页面更新)之后获取DOM,我们要把获取DOM的语法,放在setState的第二个参数里,setState的第二个参数是一个函数,我们可以把获取DOM的逻辑放在里边。setState的第二个参数会在setState异步执行完毕之后执行。这样就能保证,当第二个参数执行的时候,页面已经被更新完了,这个时候获取页面上的DOM,肯定是不会错的。
handleBtnCick(){
this.setState((prevState)=>({
list:[...prevState.list,prevState.inputValue],
inputValue:''
}))
// 这里获取的DOM并不完整,因为先执行
console.log(this.ul.querySelectorAll('div').length)
}
// setState有第二个参数,这个参数是一个函数,它会再setState异步执行完毕之后,也就是页面更新完毕后执行。
handleBtnCick(){
this.setState((prevState)=>({
list:[...prevState.list,prevState.inputValue],
inputValue:''
}),()=>{
console.log(this.ul.querySelectorAll('div').length)
})
}