帮助我们在 React 中获取DOM元素
在React 里面,可以用 e.target 获取到事件对应的元素,也可以用 ref;
1.e.target
<input
id="insertArea"
className="input"
type="text"
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
// 使用 e.target
handleInputChange (e) {
console.log (e.target); //<input id="insertArea" class="input" type="text" value="">
const {value} = e.target;
this.setState (() => ({
inputValue: value,
}));
- ref 不推荐,有时候 setState 与 ref 合用的时候会出现一些坑,DOM 的获取并不及时,原因是 setState 是异步的。
在 input 框里面可以使用 ref 的参数,在 React 16版本中,ref 应该是一个函数,这个箭头函数会自动接收到一个参数。
ref={(input)=>{this.input=input}}
//构建了一个ref 引用,这个引用叫 this.input ,它指向这个 input 对应的 DOM 节点。
<input
id="insertArea"
className="input"
type="text"
value={this.state.inputValue}
onChange={this.handleInputChange}
ref={input => {
this.input = input;
}}
/>
// 使用ref
handleInputChange (e) {
const value = this.input.value;
this.setState (() => ({
inputValue: value,
}));
}
3.使用 ref 遇到的坑
获取的 div 的长度总是比实际的少一个,
代码并没有写错
<ul
ref={ul => {
this.ul = ul;
}}
>
{this.getTodoItem ()}
</ul>
getTodoItem () {
return this.state.list.map ((item, index) => {
// return <div>item</div>
// return React.createElement('div',{},'item')
return (
<TodoItem
content={item}
index={index}
key={index}
list={this.state.list}
deleteItem={this.handleItemDelete}
/>
);
});
}
//添加项
handleBtnClick () {
this.setState (prevState => ({
list: [...prevState.list, prevState.inputValue],
inputValue: '',
}));
console.log (this.ul.querySelectorAll ('div').length);
}
因为 setState 是一个异步函数,不会立即被执行,所以 console.log (this.ul.querySelectorAll ('div').length); 先于 this.setState 执行。
如果希望 this.setState 执行成功之后,页面更新之后再去获取页面上的 DOM,正确的做法是:
把 console.log (this.ul.querySelectorAll ('div').length); 放在 this.setState 提供的第二个参数中。这个参数也是一个函数,当 this.setState 异步的执行完成之后,console.log 才会执行,它的第二个参数其实是一个回调函数,写在第二个参数中就不会有问题了。
如下
//添加项
handleBtnClick () {
// setState 可以接收 参数,prevState表示修改数据之前的那一次数据的样子
this.setState (
prevState => ({
list: [...prevState.list, prevState.inputValue],
inputValue: '',
}),
() => {
console.log (this.ul.querySelectorAll ('div').length);
}
);
}