React-06React中refs属性(字符串refs,回调形式,React.createRef() )
1.React中refs属性
绑定到render输出的任何组件上,通过this.ref.绑定名直接操作DOM元素或获取子组件的实例。
2.绑定refs实例
2.1 字符串refs(已经过时参考官网API)
字符串(string)的ref存在一定的效率问题
<input ref='input1' type="text" placeholeder='点击按钮提示数据'/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello,React</title>
</head>
<body>
<!-- 容器 -->
<div id="test"></div>
<!-- {/* // 引入 React核心库 */} -->
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<!-- {/* // 引入 react-dom 用于支持 react 操作 DOM */} -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- {/* // 引入 babel:1. ES6 ==> ES5 2. jsx ==> js */} -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- {/* // 引入 JSX 语法 */} -->
<script type="text/babel">
// 1.创建组件
class MyComponent extends React.Component {
render() {
return (
<div>
<input ref='input1' type="text" placeholeder='点击按钮提示数据'/>
<button ref='button1' onClick={this.showData}>点击提示左侧数据</button>
<input ref='input2' onBlur={this.showData2} type="text" placeholeder='失去焦点提示数据'/>
</div>
)
}
// 左侧事件处理函数 ref标识使用
showData = () => {
console.log(this);
alert(this.refs.input1.value);
}
// 右侧事件处理函数 失去焦点触发
showData2 = () => {
alert(this.refs.input2.value);
}
}
// 2. 渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />,document.getElementById('test'))
</script>
</body>
</html>
2.2 回调形式refs
<input ref={c => this.input1 = c} type="text" placeholeder='点击按钮提示数据'/>
整体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello,React</title>
</head>
<body>
<!-- 容器 -->
<div id="test"></div>
<!-- {/* // 引入 React核心库 */} -->
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<!-- {/* // 引入 react-dom 用于支持 react 操作 DOM */} -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- {/* // 引入 babel:1. ES6 ==> ES5 2. jsx ==> js */} -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- {/* // 引入 JSX 语法 */} -->
<script type="text/babel">
// 1.创建组件
class MyComponent extends React.Component {
// 回调函数 形式的ref标识使用
render() {
return (
<div>
<input ref={c => this.input1 = c} type="text" placeholeder='点击按钮提示数据'/>
<button onClick={this.showData}>点击提示左侧数据</button>
<input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholeder='失去焦点提示数据'/>
</div>
)
}
// 左侧事件处理函数 ref标识使用
showData = () => {
const {input1} =this
alert(input1.value);
}
// 右侧事件处理函数 失去焦点触发
showData2 = () => {
const {input2} =this
alert(input2.value);
}
}
// 2. 渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />,document.getElementById('test'))
</script>
</body>
</html>
2.2.1 回调函数refs以内联方式定义,更新过程中会执行两次
ref回调函数如果以内联函数的方式定义,在更新的过程中会执行两次,第一次传入null,第二次传入参数DOM元素,每次渲染时会创建新的函数实例,所以React清空旧的的ref并设置新的。影响几乎不存在
整体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello,React</title>
</head>
<body>
<!-- 容器 -->
<div id="test"></div>
<!-- {/* // 引入 React核心库 */} -->
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<!-- {/* // 引入 react-dom 用于支持 react 操作 DOM */} -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- {/* // 引入 babel:1. ES6 ==> ES5 2. jsx ==> js */} -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- {/* // 引入 JSX 语法 */} -->
<script type="text/babel">
// 1.创建组件
class MyComponent extends React.Component {
state = {isHot:true}
// 事件处理函数 ref标识使用
showData = () => {
const {input1} =this
alert(input1.value);
}
// 回调函数 形式的ref标识使用
render() {
const {isHot} = this.state
return (
<div>
<h2>{isHot?'很热':'很冷'}</h2>
<button onClick={()=>this.setState({isHot:!isHot})}>点击切换天气</button>
<input ref={c => {this.input1 = c;console.log('渲染次数:',c)}} type="text" placeholeder='点击按钮提示数据'/>
<button onClick={this.showData}>点击提示左侧数据</button>
</div>
)
}
}
// 2. 渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />,document.getElementById('test'))
</script>
</body>
</html>
2.3 React.createRef() 容器存储ref所标识的节点
2.3.1 声明调用
// 调用后返回容器(声明唯一标识使用),容器存储ref所标识的节点
myRef = React.createRef()
showData = () => {
console.log(this.myRef.current.value);
alert(this.myRef.current.value);
}
2.3.2 对应节点绑定
<input ref={this.myRef} type="text" placeholeder='点击按钮提示数据'/>
2.3.3 整体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello,React</title>
</head>
<body>
<!-- 容器 -->
<div id="test"></div>
<!-- {/* // 引入 React核心库 */} -->
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<!-- {/* // 引入 react-dom 用于支持 react 操作 DOM */} -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- {/* // 引入 babel:1. ES6 ==> ES5 2. jsx ==> js */} -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- {/* // 引入 JSX 语法 */} -->
<script type="text/babel">
// 1.创建组件
class MyComponent extends React.Component {
// 调用后返回容器(声明唯一标识使用),容器存储ref所标识的节点
myRef = React.createRef()
myRef2 = React.createRef()
// 事件处理函数
showData = () => {
console.log(this.myRef.current.value);
alert(this.myRef.current.value);
}
// 失去焦点处理函数
showData2 = () => {
console.log(this.myRef.current.value);
alert(this.myRef.current.value);
}
render() {
return (
<div>
<input ref={this.myRef} type="text" placeholeder='点击按钮提示数据'/>
<button onClick={this.showData}>点击</button>
<input ref={this.myRef2} onBlur={this.showData2} type="text" placeholeder='点击按钮提示数据'/>
</div>
)
}
}
// 2. 渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />,document.getElementById('test'))
</script>
</body>
</html>