ref是一个字符串
react官网不推荐使用字符串形式的ref,它可能在未来的某个版本被移除。 <input type="text" ref="input1"/> , <input type="text" ref="input2"/> , 组件实例的refs 属性上以key-value的形式保存着真实DOM元素。
<!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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
showData = () => {
console.log(this);
alert(this.refs.input1.value);
}
showData2 = () => {
alert(this.refs.input2.value);
}
render() {
return (
<div>
<div>
<input type="text" placeholder="点击按钮提示数据" ref="input1"/>
<button onClick={this.showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={this.showData2} ref="input2" />
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
ref是一个回调函数
回调函数是内联形式
<input type="text" ref={c => this.input1 = c}/> , <input type="text" ref={c => this.input2 = c} /> 回调函数的参数,就是真实的DOM元素。
<!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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
showData = () => {
console.log(this.input1);
alert(this.input1.value);
}
showData2 = () => {
console.log(this.input2);
alert(this.input2.value);
}
render() {
return (
<div>
<div>
<input type="text" placeholder="点击按钮提示数据" ref={c => this.input1 = c}/>
<button onClick={this.showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={this.showData2} ref={c => this.input2 = c} />
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
回调函数是内联函数时,组件更新过程会执行两次回调。回调第一次执行,返回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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
state = {
isHot:false
}
changeWeather = () => {
const {isHot} = this.state;
this.setState({
isHot:!isHot
})
}
showData = () => {
console.log(this.input1);
alert(this.input1.value);
}
showData2 = () => {
console.log(this.input2);
alert(this.input2.value);
}
render() {
const {isHot} = this.state;
const {changeWeather,showData,showData2} = this;
return (
<div>
<h2 onClick={changeWeather}>今天天气很{isHot ? "炎热" : "凉爽"}</h2>
<div>
<input type="text" placeholder="点击按钮提示数据" ref={c => {this.input1 = c;console.log("@",c)}}/>
<button onClick={showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={showData2} ref={c => this.input2 = c} />
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
react官网说,虽然更新过程中,内联形式的回调函数会执行两次,但大多数情况下无关紧要。
回调函数绑定在类实例上
<input type="text" ref={saveInput1}/> , <input type="text" ref={saveInput2} /> ,
<!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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
state = {
isHot:false
}
changeWeather = () => {
const {isHot} = this.state;
this.setState({
isHot:!isHot
})
}
saveInput1 = (c) => {
this.input1 = c;
console.log("@",c);
}
saveInput2 = (c) => {
this.input2 = c;
}
showData = () => {
console.log(this.input1);
alert(this.input1.value);
}
showData2 = () => {
console.log(this.input2);
alert(this.input2.value);
}
render() {
const {isHot} = this.state;
const {changeWeather,showData,showData2,saveInput1,saveInput2} = this;
return (
<div>
<h2 onClick={changeWeather}>今天天气很{isHot ? "炎热" : "凉爽"}</h2>
<div>
<input type="text" placeholder="点击按钮提示数据" ref={saveInput1}/>
<button onClick={showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={showData2} ref={saveInput2} />
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
createRef
myRef = React.createRef() ,createRef() 将返回一个容器,用于保存ref标识的节点。<input type="text" ref={myRef}/> ,ref 属性标识目标元素。this.myRef.current ,访问目标元素。
<!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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
myRef = React.createRef();
myRef2 = React.createRef();
showData = () => {
console.log(this.myRef);
alert(this.myRef.current.value);
}
showData2 = () => {
console.log(this.myRef2);
alert(this.myRef2.current.value);
}
render() {
const {showData,showData2,myRef,myRef2} = this;
return (
<div>
<div>
<input type="text" placeholder="点击按钮提示数据" ref={myRef}/>
<button onClick={showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={showData2} ref={myRef2} />
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
不要过度使用ref
不要过度使用ref 。比如,上述例子里,第二个input 就没必要用ref ,在事件回调中使用event.target 即可获取输入框的文本值。
<!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>test</title>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
myRef = React.createRef();
showData = () => {
alert(this.myRef.current.value);
}
showData2 = (event) => {
alert(event.target.value);
}
render() {
const {showData,showData2,myRef,myRef2} = this;
return (
<div>
<div>
<input type="text" placeholder="点击按钮提示数据" ref={myRef}/>
<button onClick={showData}>点我提示数据</button>
</div>
<input type="text" placeholder="失去焦点提示数据" onBlur={showData2}/>
</div>
)
}
}
ReactDOM.render(<Login />, document.getElementById("app"));
</script>
</body>
</html>
|