Consider a file uploader called Uploader:
1export type UploaderHandle = {
2 fileIdArrs: number[],
3 postFilesToServer: () => Promise<number[]>,
4}
5
6type UploaderProps = {
7 documents: SomeFile[],
8}
9
10const Uploader = forwardRef<UploaderHandle, UploaderProps>((props, ref) => {
11 const { documents } = props
12 useImperativeHandle(ref, () => ({
13 fileIdArrs,
14 postFilesToServer,
15 }))
16 ...
17 const [fileIdArrs, setfileIdArrs] = useState<number[]>([]);
18
19 const postFilesToServer = async () => {
20 for (let file of fileList) {
21 await uploadFile(file);
22 ...
23 }
24 }
25})
- We want the method to be triggered by the parent of
<Uploader/> instead.
- Sometimes it is done for the purpose of code separation (e.g., its parent is already complicated enough).
Now consider a parent that makes use of <Uploader/>:
1export default function SomeComponent() {
2 const uploaderRef = useRef<UploaderHandle>(null);
3 ...
4 const saveHandler = async () => {
5 const fileIds = await uploaderRef.current?.postFilesToServer();
6 ...
7 }
8 return(
9 ...
10 <Box>
11 <Uploader
12 documents={documents}
13 ref={uploaderRef}
14 />
15 </Box>
16 )
17}
In line 5 we use the method postFilesToServer which belongs to its child <Uploader/>.