ref是为了获取节点或者子组件的实例
ref在节点上,获取到的是节点元素
ref在classComponent上获取到的是组件实例
ref在functionComponent上是无效的,因为functionComponent没有实例
大部分我们是获取classCompoent实例,但是有时候会获取定义的是functionCompoent,
比如一个PrueComponent就是一个functionCompoent
const TargetComponent=(props)=>{
<input type="text"/>
}
问题
个人开发者,可以避免在functionComponent上使用ref,如果组件库或者框架开发时,使用者是不清楚,组件库提供的classComponent还是functionComponent
ref是不会跟着props下发下来的
refs目前主要的使用方式有两种
第一种
refs回调(传递给子组件的ref属性一个方法,子组件渲染时候会调用传递下去的方法,方法的参数中带有子组件的元素,这样父组件就拿到了子组件元素的实例)
import React from 'react'
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class RefsTest extends React.Component {
constructor(props) {
super(props)
this.inputElement = null;
this.focusTextInput = this.focusTextInput.bind(this)
}
focusTextInput = () => {
this.inputElement.focus();
};
// 将ref回调函数定义成class的绑定函数,避免每次渲染都会创建一个新的函数实例
inputRefFun = (el) => {
this.inputElement = el
}
render() {
return (
<div>
<CustomTextInput
inputRef={this.inputRefFun}
/>
<button onClick={this.focusTextInput}>点击</button>
</div>
);
}
}
export default RefsTest;
第二种
使用react提供的forwarRef()方法,配合高阶组件
import React from 'react'
function CustomTextInput(props) {
console.log(props)
return (
<div>
<input ref={props.forwardedRef} />
</div>
);
}
function WithRefHOC(Component) {
class WithRefComponent extends React.Component {
render() {
const {
forwardedRef,
...rest
} = this.props;
return (
<Component forwardedRef={forwardedRef} {...rest}></Component>
)
}
}
return React.forwardRef((props, ref) => {
console.log(props, ref)
return <WithRefComponent {...props} forwardedRef={ref}></WithRefComponent>
})
}
const TextInput = WithRefHOC(CustomTextInput)
const inputRef = React.createRef('b');
function RefsHOCTest() {
const focusTarget = () => {
console.log(inputRef.current)
inputRef.current.focus()
}
return (
<div>
<TextInput ref={inputRef} name="aa"></TextInput>
<button onClick={focusTarget}>点击</button>
</div>
)
}
export default RefsHOCTest;