refs属性有三种书写方式
- 字符串形式(简单,但可能被废弃)
- 回调形式(开发用的最多)
- createRef形式(官方推荐)
字符串形式 ref
- 注意:过度使用字符串
ref
会存在效率问题,该方式可能会在未来的版本中移除
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
showData =()=>{
const {left} =this.refs;
alert(left.value)
}
showData2 = ()=>{
const {right} = this.refs;
alert(right.value)
}
render() {
return (
<div>
<input ref='left' type="text" placeholder="点击右侧按钮弹出该框的内容" />
<button ref='buttonmid' onClick={this.showData}>点我提示左侧输入框内容</button>
<input ref='right' onBlur={this.showData2} type="text" placeholder="失去焦点提示该框的内容"/>
</div>
)
}
}
ReactDOM.render(<Demo/>,document.getElementById('test'))
</script>
回调形式 ref
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
showData =()=>{
const {left} =this;
alert(left.value)
}
showData2 = ()=>{
console.log(this);
const {right} = this;
alert(right.value)
}
render() {
return ( // 回调方法中向实例自身上挂一个left和right属性,
<div>
<input ref={(c)=>{this.left = c}} type="text" placeholder="点击右侧按钮弹出该框的内容" />
<button onClick={this.showData}>点我提示左侧输入框内容</button>
<input ref={c=> this.right = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示该框的内容"/>
</div>
)
}
}
ReactDOM.render(<Demo/>,document.getElementById('test'))
小问题:
- 传入内联回调,在更新时,该内联回调会调用两次
- 第一次,接收到的参数为
null
,是为了清空状态 - 第二次,接收到的参数为绑定的标签
解决小问题方法:
传入非内联函数(定义成calss的绑定函数方式),在更新时,不会重复调用
<div id="test"></div>
<script type="text/javascript" src="../JS/react.development.js"></script>
<script type="text/javascript" src="../JS/react-dom.development.js"></script>
<script type="text/javascript" src="../JS/babel.min.js"></script>
<script type="text/javascript" src="../JS/prop-types.js"></script>
<script type="text/babel">
class Demo extends React.Component {
// 定义成class的绑定函数方式
saveInput(c){
this.left = c;
console.log('@',c);
}
render() {
return ( // 回调方法中向实例自身上挂一个left和right属性,
<div>
{/*<input ref={(c)=>{this.left = c;console.log('@',c);}} type="text" placeholder="点击右侧按钮弹出该框的内容" />*/}
<input ref={this.saveInput} type="text" placeholder="点击右侧按钮弹出该框的内容" />
</div>
)
}
}
ReactDOM.render(<Demo/>,document.getElementById('test'))
createRef()
- 被
React
推荐使用的形式 createRef()
方法创建的容器只能容纳一个ref
节点,若需要操作多个ref
节点,则需要创建多个容器
class Demo extends React.Component {
// React.createRef调用后返回一个容器,该容器可以存储被ref所标识的节点 "专人专用"! 只能存一个!
myRef = React.createRef()
// myRef2 = React.createRef()
showData = () => {
alert(this.myRef.current.value);
}
showData2 = () => {
alert(this.myRef2.current.value)
}
render() {
return ( // 回调方法中向实例自身上挂一个left和right属性,
<div>
<input ref={this.myRef} type="text" placeholder="点击右侧按钮弹出该框的内容" />
<button onClick={this.showData}>点我提示左侧输入框内容</button>
<input ref={this.myRef2 = React.createRef()} onBlur={this.showData2} type="text" placeholder="失去焦点提示该框的内容" />
</div>
)
}
}
ReactDOM.render(<Demo />, document.getElementById('test'))
ref的使用要尽量的减少
减少方式:
若发生事件的元素正好是需要操作的元素,则可以省略ref的使用。ex:利用event.target属性进行对ref的替换使用。
举例说明:
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
// React.createRef调用后返回一个容器,该容器可以存储被ref所标识的节点 "专人专用"! 只能存一个!
myRef = React.createRef()
// myRef2 = React.createRef()
showData = () => {
alert(this.myRef.current.value);
}
showData2 = (event) => {
alert(event.target.value)
}
render() {
return ( // 回调方法中向实例自身上挂一个left和right属性,
<div>
<input ref={this.myRef} type="text" placeholder="点击右侧按钮弹出该框的内容" />
<button onClick={this.showData}>点我提示左侧输入框内容</button>
{/*
若发生事件的元素正好是需要操作的元素,则可以省略ref的使用。
*/}
<input onBlur={this.showData2} type="text" placeholder="失去焦点提示该框的内容" />
</div>
)
}
}
ReactDOM.render(<Demo />, document.getElementById('test'))