1. forwardRef
forwardRef
允许组件使用 ref 将 DOM 节点暴露给父组件。
【案例】:聚焦文本输入框
const DanoChirld=(props:any)=>{
return(<Input ref={props.ref}></Input>)
}
const Damo = () => {
const butRef=useRef(null)
return (
<div>
<DanoChirld ref={butRef}/>
<Button onClick={()=>{
console.log(butRef.current)
}}>编辑</Button>
</div>
);
}
export default Damo;
直接通过将ref传参到函数子组件,报错!!!
控制台报错,说函数组件不能接受ref
的外部数据。打印出子组件的props
,ref:undifine
,ref
没进来。外边虽然传了一个ref
,但是一个函数组件找不到这个ref
,读不到。
【原因】: 函数组件无法接收ref的props
【解决办法】:使用 forwardRef传递ref
如果你的函数组件想要接受别人传来的ref参数,就必须把函数组件用 forwardRef
包起来。这样就可以接受ref作为第二个参数。不然就只有props这一个参数。forwardRef
会把别人传给你的ref帮你传进来。
const DanoChirld=forwardRef((props:any,ref:any)=>{
return(<Input ref={ref}></Input>)
})
const Damo = () => {
const butRef=useRef(null)
return (
<div>
<DanoChirld ref={butRef}/>
<Button onClick={()=>{
console.log(butRef.current)
butRef.current.focus()//聚焦
}}>编辑</Button>
</div>
);
}
export default Damo;
【注】: 类组件是不需要的,可以直接传
2.useInperativeHandle
通过ref暴露子组件中的方法
const DanoChirld = forwardRef((props: any, ref: any) => {
const inputRef = useRef(null)
const focusFun = () => {
inputRef.current.focus()
}
useImperativeHandle(ref, () => {
return {
focusFun
}
})
return (<Input ref={inputRef}></Input>)
})
const Damo = () => {
const butRef = useRef(null)
return (
<div>
<DanoChirld ref={butRef} />
<Button onClick={() => {
butRef.current.focusFun()
console.log(butRef.current)
}}>编辑</Button>
</div>
);
}
export default Damo;
console.log(butRef.current)
【注】:
forwardRef
和useImperativeHandle
配合使用将子组件的方法暴露给父组件;- 子传父通信也是同理!
const DanoChirld = forwardRef((props: any, ref: any) => {
const inputRef = useRef<InputRef>(null)
const [value,setValue] = useState("")
useImperativeHandle(ref, () => {
return {
focusFun(){
inputRef.current?.focus()
},
value
}
},[value])
return (<Input ref={inputRef} value={value} onChange={({target:{value}})=>{setValue(value)}}></Input>)
})
const Damo = () => {
const butRef = useRef<{focusFun(): void;value:string}>(null)
return (
<div>
<DanoChirld ref={butRef} />
<Button onClick={() => {
butRef.current?.focusFun()
console.log(butRef.current)
}}>编辑</Button>
<Button type='default' onClick={()=>{
console.log(butRef.current?.value);
}}>value</Button>
</div>
);
}
export default Damo;