<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="main"></div>
<script type="text/babel">
class MyComponent extends React.Component{
state = {
count:0
}
render(){
return (<div>
<input type="text" ref={(node)=>{
this.input = node
console.log("调用回调函数",node)
}}/>
<br/>
<button onClick={()=>{this.print()}}>打印</button>
<br/>
<button onClick={()=>{this.refresh()}}>刷新</button>
</div>)
}
refresh(){
this.setState({count:this.state.count+1})
}
print(){
console.log(this.input.value)
}
}
ReactDOM.render(<MyComponent/>,document.getElementById('main'))
</script>
</body>
</html>
每次刷新,回调函数都会调用两次,且第一次节点对象总是null
官方解释:如果ref
回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数null,
第二次传入参数DOM元素,这是因为在每次渲染时会创建一个新的函数实例,所以React清空旧的ref并设置新的。
改成以下形式可避免:
<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="main"></div>
<script type="text/babel">
class MyComponent extends React.Component{
state = {
count:0
}
setRef = (node)=>{
this.input = node
console.log("调用回调函数",node)
}
render(){
return (<div>
<input type="text" ref={this.setRef}/>
<br/>
<button onClick={()=>{this.print()}}>打印</button>
<br/>
<button onClick={()=>{this.refresh()}}>刷新</button>
</div>)
}
refresh(){
this.setState({count:this.state.count+1})
}
print(){
console.log(this.input.value)
}
}
ReactDOM.render(<MyComponent/>,document.getElementById('main'))
</script>
</body>
</html>