使用场景
forward Ref会将子组件的实例直接暴露给父组件,父组件可以对子组件实例做任意的操作,那么,useImperativeHandle就是来解决这个问题的,useImperativeHandle可以让我们选择暴露一些我们需要被特殊处理的操作。
简单说明:一些可用到的解决方法。
1 当请求接口在子业务组件中,然后子组件的请求接口参数在父组件中改变,多个参数的改变导致子组件多次调用接口的问题(前提:在大业务组件中写请求接口,该组件的代码量会非常大)
【其他解决:应该接口请求的参数可以通过一个对象传入,父组件的相关参数需要放置在一个对象内,子组件在判断参数的变化进行触发请求接口】
2 当子组件触发某方法时,父组件需要进行某种操作时,而子组件的某方法并没有暴露【其他解决:将子组件的方法暴露出去】
父组件
import { useRef } from 'react';
import SubList from '@/pages/NoteBook/components/SubList';
export default function Main(props) {
const { } = props;
const subRef = useRef(null);
const handleButton = () => {
if (subRef.current) {
console.log('subRef.current', subRef.current);
subRef.current.getSubList()
}
}
return (
<>
<div>
<button onClick={handleButton}>点击</button>
</div>
<SubList ref={subRef} />
</>
)
}
useImperativeHandle语法
useImperativeHandle(ref, createHandle, [deps])
forwardRef语法
const Child = forwardRef((props,ref) => {
const {} = props;
return(
<></>
)
})
不要直接使用forward Ref,forward Ref应该与useImperativeHandle一起使用
子组件
import React,{ useImperativeHandle, forwardRef, useState } from "react";
const SubList = forwardRef((props, ref) => {
const { } = props;
const [list, setList] = useState([])
// 请求接口方法
const getApi = () => {
setList([33, 55, 'GGG']);
}
useImperativeHandle(ref, () => ({
getSubList: () => {
getApi()
}
}))
return (
<>
<div>
I'm Child Components
<ul>
{
list?.map((v, index) => {
return (
<li key={v + index}>{v}</li>
)
})
}
</ul>
</div>
</>
)
})
export default SubList;