文章目录
1. 字符串形式的refs
- 组件内的标签可以通过设置ref属性值来标记自己;
- 类似于JavaScript中的id属性;
- 下面例子中 this.refs.input01拿到的是真实dom,不是虚拟dom;
- react官方未来会弃用这种方式;
- 弃用原因:就是string类型的refs存在效率问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>字符串形式的refs</title>
</head>
<body>
<!--1.准备好容器-->
<div id="root"></div>
<!--2.引入js文件-->
<script type="application/javascript" src="../js/react.development.js"></script>
<script type="application/javascript" src="../js/react-dom.development.js"></script>
<script type="application/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
//3.1 创建组件
class Demo extends React.Component{
render(){
return (
<div>
<input ref="input01" type="text" placeholder="点击按钮提示左侧input框"/>
<button onClick={this.showData_left}>点击弹窗</button>
<input ref="input02" onBlur={this.showData_right} type="text" placeholder="失去焦点提示右侧input框"/>
</div>
);
}
//中间按钮的点击方法
showData_left = ()=>{
console.log(this.refs.input01);
const {input01} = this.refs;
alert(input01.value);
}
//右边input框失去焦点方法
showData_right = ()=>{
const input02 = this.refs.input02;
alert(input02.value);
}
}
//3.2 渲染组件到页面
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</body>
</html>
2. 内联回调形式的refs
2.1 什么是 回调函数
- 用户定义的函数
- 自己没有调用
- 最终会被执行
- ()=>{} 箭头函数就是一种回调函数
2.2 内联回调形式ref
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回调形式的refs</title>
</head>
<body>
<!--1.准备好容器-->
<div id="root"></div>
<!--2.引入js文件-->
<script type="application/javascript" src="../js/react.development.js"></script>
<script type="application/javascript" src="../js/react-dom.development.js"></script>
<script type="application/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
//3.1 创建组件
class Demo extends React.Component{
render(){
return (
<div>
<input ref={(currentNode)=>{this.input01 = currentNode}} type="text" placeholder="点击按钮提示左侧input框"/>
<button onClick={this.showData_left}>点击弹窗</button>
<input ref={(c)=>{this.input02 = c}} onBlur={this.showData_right} type="text" placeholder="失去焦点提示右侧input框"/>
</div>
);
}
//中间按钮的点击方法
showData_left = ()=>{
console.log("input01= ",this.input01);
const {input01} = this;
alert(input01.value);
}
//右边input框失去焦点方法
showData_right = ()=>{
console.log("input02= ",this.input02);
const input02 = this.input02;
alert(input02.value);
}
}
//3.2 渲染组件到页面
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</body>
</html>
- 分析
ref={(currentNode)=>{this.input01 = currentNode}}
可以在 showData_left(){}中添加一个控制台打印 this ;
发现this自身已经添加了input01和input02属性;
- 总结: 回调式ref相当于把所在节点绑定到组件的实例对象上面
2.3 内联回调函数的问题
- 内联回调函数在react初始化的时候执行一次;
- 内联回调函数在react执行更新的时候,state状态每次更新都会调用两次;
- 第一次是清空上一次的内联函数,包括函数的参数,所以会把currentNode赋值为null
ref={(currentNode)=>{this.input01 = currentNode}}
所以在state状态更新的时候出现两次输出,并且第一次 ref 获取的值为null
- 第二次调用ref为新建函数并调用,属于正常调用;
- 看实例,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回调形式的refs</title>
</head>
<body>
<!--1.准备好容器-->
<div id="root"></div>
<!--2.引入js文件-->
<script type="application/javascript" src="../js/react.development.js"></script>
<script type="application/javascript" src="../js/react-dom.development.js"></script>
<script type="application/javascript" src="../js/babel.min.js"></script>
<script type="application/javascript" src="../js/prop-types.js"></script>
<script type="text/babel">
//3.1 创建组件
class Demo extends React.Component{
render(){
return (
<div>
<h2>今天天气很{this.state.isHot?"炎热":"凉爽"}</h2>
<input ref={(currentNode)=>{this.input01 = currentNode; console.log("ref回调 currentNode=",currentNode)}} type="text" placeholder="点击按钮提示左侧input框"/>
<br/><br/>
<button onClick={this.showData_left}>点击弹窗</button>
<button onClick={this.changeWeather}>切换天气</button>
</div>
);
}
//中间按钮的点击方法
showData_left = ()=>{
// console.log("this = ", this);
// console.log("input01= ",this.input01);
const {input01} = this;
alert(input01.value);
}
state = {isHot:true};
changeWeather = ()=>{
const isHot = this.state.isHot;
this.setState({isHot:!isHot});
console.log(isHot?"炎热":"凉爽");
}
}
//3.2 渲染组件到页面
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</body>
</html>
结果如下图:
3. class绑定函数调用refs
- 把ref绑定到class的实例上
- 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回调形式的refs</title>
</head>
<body>
<!--1.准备好容器-->
<div id="root"></div>
<!--2.引入js文件-->
<script type="application/javascript" src="../js/react.development.js"></script>
<script type="application/javascript" src="../js/react-dom.development.js"></script>
<script type="application/javascript" src="../js/babel.min.js"></script>
<script type="application/javascript" src="../js/prop-types.js"></script>
<script type="text/babel">
//3.1 创建组件
class Demo extends React.Component{
render(){
return (
<div>
<h2>今天天气很{this.state.isHot?"炎热":"凉爽"}</h2>
<input ref={this.setInput} type="text" placeholder="点击按钮提示左侧input框"/>
<br/><br/>
<button onClick={this.showData_left}>点击弹窗</button>
<button onClick={this.changeWeather}>切换天气</button>
</div>
);
}
//中间按钮的点击方法
showData_left = ()=>{
// console.log("this = ", this);
// console.log("input01= ",this.input01);
const {input01} = this;
alert(input01.value);
}
state = {isHot:true};
changeWeather = ()=>{
const isHot = this.state.isHot;
this.setState({isHot:!isHot});
console.log(isHot?"炎热":"凉爽");
}
setInput = (currentNode)=>{
this.input01 = currentNode;
console.log("class绑定方法 ref");
console.log("setInput currentNode", currentNode);
}
}
//3.2 渲染组件到页面
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</body>
</html>
- 输出结果:
4. createRef的调用refs(React官方推荐)
- React.createRef() 创建一个容器存放当前ref所在节点;
- 容器和元素节点是一对一的,即一个容器只存一个元素节点;
- 使用一个元素节点,就要创建一个ref对象;
- 获取ref所在节点元素 this.myRef.current
- 官方推荐使用
- 举例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回调形式的refs</title>
</head>
<body>
<!--1.准备好容器-->
<div id="root"></div>
<!--2.引入js文件-->
<script type="application/javascript" src="../js/react.development.js"></script>
<script type="application/javascript" src="../js/react-dom.development.js"></script>
<script type="application/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
//3.1 创建组件
class Demo extends React.Component{
myRef = React.createRef();
myRef2 = React.createRef();
render(){
return (
<div>
<input ref={this.myRef} type="text" placeholder="点击按钮提示左侧input框"/>
<button onClick={this.showData_left}>点击弹窗</button>
<input ref={this.myRef2} onBlur={this.showData_right} type="text" placeholder="失去焦点提示右侧input框"/>
</div>
);
}
//中间按钮的点击方法
showData_left = ()=>{
console.log("this.myRef = ", this.myRef);
console.log("this.myRef.current = ",this.myRef.current);
alert(this.myRef.current.value);
}
//右边input框失去焦点方法
showData_right = ()=>{
console.log("myRef2= ",this.myRef2.current);
alert(this.myRef2.current.value);
}
}
//3.2 渲染组件到页面
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</body>
</html>
- 输出结果如下: