forwardRef
2023年10月11日
一、认识
React.forwardRef()
会创建一个React
组件,这个组件能够将其接受的 ref
属性转发到其组件树下的另一个组件中。这种技术并不常见,但在以下两种场景中特别有用:
-
转发
refs
到DOM
组件 -
在高阶组件中转发
refs
forwardRef
让 ref
可以通过 props
传递,那么如果用 ref
对象标记的 ref
,那么 ref
对象就可以通过 props
的形式,提供给子孙组件消费,当然子孙组件也可以改变 ref
对象里面的属性,或者像如上代码中赋予新的属性,这种 forward + ref
模式一定程度上打破了 React
单向数据流动的原则。当然绑定在 ref
对象上的属性,不限于组件实例或者 DOM
元素,也可以是属性值或方法。
二、语法
2.1 forwardRef(functionName)
- 父组件
- 子组件
import React, { useRef } from 'react';
import MyInput from './MyInput.js';
type RefType = {
a: string;
b: string;
}
export default function Form() {
const ref = useRef<RefType>(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
import { forwardRef } from 'react';
type RefType = {
a: string;
b: string;
}
type PropsType = {
}
const MyInput = function MyInput(props: PropsType, ref: React.ForwardedRef<RefType>) {
return (
<label>
{label}
<input ref={ref} />
</label>
);
}
const forWardRefMyInput = forwardRef<RefType,PropsType>(MyInput);
export default forWardRefMyInput;
2.2 forwardRef(functionBody)
- 父组件
- 子组件
import React, { useRef } from 'react';
import MyInput from './MyInput.js';
type RefType = {
a: string;
b: string;
}
export default function Form() {
const ref = useRef<RefType>(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
import { forwardRef } from 'react';
type RefType = {
a: string;
b: string;
}
type PropsType = {
}
const forWardRefMyInput = forwardRef<RefType,PropsType>(function MyInput(props: PropsType, ref: React.ForwardedRef<RefType>) {
return (
<label>
{label}
<input ref={ref} />
</label>
);
});
export default forWardRefMyInput;
2.3 forwardRef(()=>{ return <> })
- 父组件
- 子组件
import React, { useRef } from 'react';
import MyInput from './MyInput.js';
type RefType = {
a: string;
b: string;
}
export default function Form() {
const ref = useRef<RefType>(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
import { forwardRef } from 'react';
type RefType = {
a: string;
b: string;
}
type PropsType = {
}
function MyInput(props: PropsType & React.ForwardedRef<RefType>) {
return (
<label>
{label}
<input ref={ref} />
</label>
);
}
const forWardRefMyInput = forwardRef<RefType,PropsType>((props: PropsType,ref: React.ForwardedRef<RefType>)=>{
return <MyInput {...props} ref={MyInput} />
});
export default forWardRefMyInput;