0%
August 14, 2023

forwardRef and useImperativeHandle

react

Consider a file uploader called Uploader:

export type UploaderHandle = {
    fileIdArrs: number[],
    postFilesToServer: () => Promise<number[]>,
}

type UploaderProps = {
    documents: SomeFile[],
}

const Uploader = forwardRef<UploaderHandle, UploaderProps>((props, ref) => {
    const { documents } = props
    useImperativeHandle(ref, () => ({
        fileIdArrs,
        postFilesToServer,
    }))
    ...
    const [fileIdArrs, setfileIdArrs] = useState<number[]>([]);

    const postFilesToServer = async () => {
        for (let file of fileList) {
          await uploadFile(file);
          ...
        }
    }
})
  • 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/>.