在一些特殊情况下,React也需要对DOM进行一些操作,这时就要用到——ref。
1)例子:用上一节的Counter.js项目来理解,实现获取增加按钮距离浏览器窗口顶部的距离。
import React,{ Component,Fragment } from ‘react‘;
import Child from ‘./Child‘
class Counter extends Component{
constructor(props) {
super(props);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.state = {
counter:1
}
}
handleBtnClick(){
// console.log(this.buttonElem);//button节点
// console.log(this.buttonElem.clientTop);
const newCounter = this.state.counter + 1;
this.setState({
counter:newCounter
});
}
render() {
return (
<Fragment>
<button onClick = {this.handleBtnClick}
ref = {(button) => {this.buttonElem =
button}}
>
增加
</button>
<Child number = {this.state.counter}/>
</Fragment>
)
}
}
export default Counter;
ref 写在html标签上,获取的是DOM节点;
ref 写在组件标上,获取的是组件的JS实例。
2)setState是异步的!
import React,{ Component,Fragment } from ‘react‘;
class Counter extends Component{
constructor(props) {
super(props);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.state = {
counter:1
}
}
handleBtnClick(){
const newCounter = this.state.counter + 1;
console.log(this.divElem.innerHTML);//第一个
this.setState({
counter:newCounter
});
console.log(this.divElem.innerHTML);//第二个
}
render() {
return (
<Fragment>
<button onClick = {this.handleBtnClick} >增加</button>
<div ref = {(div)=>{this.divElem = div}}>{this.state.counter}</div>
</Fragment>
)
}
}
export default Counter;
上面的代码中,每当点击一次按钮,两个console输出的都是相同的数字,这是因为setState是异步的,在第二个cosole执行时,可能还没有执行它,因此没有输出更改后的值。
我们可以将setState方法做一些修改,在里面传递两个函数参数,在setState把数据改变之后会执行第二个函数,这时第二个console输出的就是改变后的值了!
handleBtnClick(){
const newCounter = this.state.counter + 1;
console.log(this.divElem.innerHTML);
this.setState(() => {
return {
counter:newCounter
}
},()=>{
console.log(this.divElem.innerHTML);
})
}

需求:在input中输入内容,当点击按钮之后,通过ref获取Dom节点的内容,把获取出来的内容输出在控制台。
以下是我的实现代码:
import React,{ Component,Fragment } from ‘react‘;
class Ref extends Component{
constructor(props) {
super(props);
this.handleInputElem = this.handleInputElem.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.state = {
content:‘‘
}
}
handleInputElem() {
const newContent = this.state.content;
this.setState(()=>{
return {
content:newContent
}
},()=>{
console.log(this.inputElem.value);
});
}
handleInputChange(e) {
this.setState({
content:e.target.value
})
}
render() {
return (
<Fragment>
<input value = {this.state.content} ref = {(input)=>{this.inputElem = input}} onChange = {this.handleInputChange}></input>
<button onClick = {this.handleInputElem}>提交</button>
</Fragment>
)
}
}
export default Ref;
原文:https://www.cnblogs.com/superjishere/p/12101656.html