场景: 希望直接使用dom元素中的某个方法(如focus),或者希望直接使用自定义组件中的某个方法
render() {
return (
// this.refs.input 得到的是dom对象
<input ref='input' />
)
}
render() {
return (
// this.refs.input 得到的是实例对象
<MyClassComponent ref='input' />
)
}
ref不再推荐使用如上JS代码中的字符串赋值形式 未来可能会移除这种赋值方式
目前, ref推荐使用对象或者函数
通过 React.createRef 创建
import React, { Component } from 'react'
export default class RefClass extends Component {
constructor(props) {
super(props)
this.input = React.createRef()
}
render() {
return (
// this.input = { current: Dom对象 }
// 使用: this.input.current.xxx
<div ref={this.input}></div>
)
}
}
import React, { Component } from 'react'
export default class Ref extends Component {
handleClick = () => {
console.log('this', this)
this.setState({})
}
render() {
return (
<div>
<input ref={el=> {
console.log('调用了', el)
this.ele = el
}} type="text" />
<button onClick={this.handleClick}>点击吧</button>
</div>
)
}
}
import React, { Component } from 'react'
export default class Ref extends Component {
handleClick = () => {
console.log('this', this)
this.setState({})
}
getInputRef = el => {
console.log('调用了', el)
this.ele = el
}
render() {
return (
<div>
<input ref={this.getInputRef} type="text" />
<button onClick={this.handleClick}>点击吧</button>
</div>
)
}
}
import React, { Component } from 'react'
// 2. 被转发的函数组件必须有第二个参数来接受被转发的ref
function A(props, ref) {
return (
// 3. 此时myRef指向h1元素
<h1 ref={ref}>组件A</h1>
)
}
// 1. 通过React.forwardRef可以转发ref, 参数传递***函数***组件,返回一个组件
const NewA = React.forwardRef(A)
export default class App extends Component {
myRef = React.createRef()
componentDidMount() {
// 4. 得到想要的h1元素
console.log('myRef', this.myRef)
}
render() {
return (
<div>
<NewA ref={this.myRef}/>
</div>
)
}
}
import React, { Component } from 'react'
// 3. 使用约定好的属性forwardRef绑定到h1元素
class A extends React.Component {
render() {
return (
<h1 ref={this.props.forwardRef}>类组件A</h1>
)
}
}
// 1. 通过React.forwardRef可以转发ref, 参数传递***函数***组件,返回一个组件
const NewA = React.forwardRef((props, ref) => {
// 2. 约定一个自定义属性名(本例forwardRef)用于转发ref
return <A {...props} forwardRef={ref} />
})
export default class App extends Component {
myRef = React.createRef()
componentDidMount() {
// 4. 得到想要的h1元素
console.log('myRef', this.myRef)
}
render() {
return (
<div>
<NewA ref={this.myRef}/>
</div>
)
}
}
高阶组件withLog.js
import React from 'react'
export default function withLog(Comp) {
class LogContainer extends React.Component {
componentDidMount() {
console.log(`组件: ${Comp.name}被创建了`)
}
componentWillUnmount() {
console.log(`组件: ${Comp.name}被销毁了`)
}
render() {
// 解构属性
const { forwardRef, ...rest } = this.props
return (
// 属性传递
<Comp ref={forwardRef} {...rest} />
)
}
}
return React.forwardRef((props, ref)=> {
// 约定forwardRef用于转发ref
return <LogContainer {...props} forwardRef={ref} />
})
}
App.js
import React, { Component } from 'react'
import { A } from './components/testHOC'
import withLog from './HOC/withLog'
// 高阶组件
const AComp = withLog(A)
export default class App extends Component {
myRef = React.createRef()
componentDidMount() {
// 经过高阶组件处理,现在myRef将指向A组件
console.log('myRef', this.myRef)
}
render() {
return (
<div>
<AComp ref={this.myRef} isLogin a='a' />
</div>
)
}
}