ref的作用是让我们快速的绑定节点并获取到节点,三种绑定方式分别是字符串
、回调函数
,createRef()
参考
https://www.wekic.com/article/10
使用场景
- 对Dom元素的焦点控制、内容选择、控制
- 对Dom元素的内容设置及媒体播放
- 对Dom元素的操作和对组件实例的操作
- 集成第三方 DOM 库
1. createRef (类组件)
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount(){
this.myRef.current.focus();
}
render() {
return <Input ref={this.myRef}/>;
}
}
2.useRef (函数组件)
情况一:直接挂在Dom元素上
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
情况二: 挂载在子组件上
const Child=React.forwardRef((props, ref)=> {
return (
<>
<input type="text" ref={ref}/>
</>
)
})
const Parent = () => {
const ref = React.createRef();
const focus = () => {
ref.current.focus()
}
return (
<>
<Child ref={ref}/>
<button onClick={focus}>获得焦点</button>
</>
)
}
export default Parent
/*********************************************************************/
useImperativeHandle可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle
应当与 forwardRef
一起使用
const Child=React.forwardRef((props, ref)=> {
const inputRef=useRef()
useImperativeHandle(ref, () => ({
inputfocus: () => {
inputRef.current.focus()
}
}));
return (
<>
<input type="text" ref={inputRef}/>
</>
)
})
const Parent=()=> {
const ref = useRef();
const focus=()=>{
ref.current.inputfocus()
}
return (
<>
<Child ref={ref}/>
<button onClick={focus}>获得焦点</button>
</>
)
}
export default Parent
3. refs回调
https://zh-hans.reactjs.org/docs/refs-and-the-dom.html#callback-refs
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
if (this.textInput) this.textInput.focus();
};
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();
}
render() {
// 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
return (
<input
type="text"
ref={element => this.textInput = element}
/>
);
}
}
export default CustomTextInput
可以在组件间传递回调形式的 refs,就像你可以传递通过 React.createRef() 创建的对象 refs 一样
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
);
}
}
4.String 类型的 Refs
字符串类型的refs不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
this.refs.textInput.focus()
};
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();
}
render() {
return (
<input
type="text"
ref='textInput'
/>
);
}
}
export default CustomTextInput
useRef和createRef的区别
-
useRef 一般用于函数组件
useRef 不仅仅是用来管理 DOM ref 的,它还相当于 this , 可以存放任何变量。
当 useRef 的内容发生变化时,它不会通知您。更改.current属性不会导致组件重新渲染。因为他一直是一个引用 。 -
createRef一般用于类组件,
React.createRef 创建一个能够通过 ref 属性附加到 React 元素的 ref。
如果用于函数组件中,当App这个函数组件被重新渲染时,App函数将会执行,并且重新创建、初始化所有的变量和表达式。因此,createRef每次都会被执行,所以对应的值总是为null。
createRef 每次渲染都会返回一个新的引用,而 useRef 每次都会返回相同的引用。
网友评论