使用React.forwardRef传递泛型参数
React.forwardRef传递泛型参数
使用React函数组件开发的过程中会遇到父组件调用子组件的方法或者属性的场景,首次先说怎么通过React.forwardRef来将子组件的属性或者方法暴露给父组件
使用forwardRef暴露组建的方法和属性
子组件
import { Box, Typography } from "@mui/material"; import { forwardRef, useImperativeHandle } from "react"; interface LocationChildProps { data: string; } export interface LocationChildRef { sayType(): void; } const LocationChild = forwardRef<LocationChildRef, LocationChildProps>((props, ref) => { useImperativeHandle(ref, () => ({ sayType() { console.log("子组件的data是 " + typeof props.data); }, })); return ( <Box> <Typography>{typeof props.data}</Typography> </Box> ); }); export default LocationChild;
在子组件中我们需要接受一个key为data的props,然后在子组件中展示这个值,并且通过useImperativeHandle向外暴露一个sayType的方法, 最后用forwardRef将子组件封装然后暴露出去,这里forwardRef的作用就是包装该组件为一个可以通过Ref访问的组件。
父组件
import { Button } from "@mui/material"; import { useRef } from "react"; import ConfigDetailContainer from "../options/ConfigDetailContainer"; import LocationChild, { LocationChildRef } from "./LocationChild"; export default function DeviceLocation() { const locationChildRef = useRef<LocationChildRef>(); const handleClick = () => { locationChildRef.current.sayType() // 输出: 子组件的type是 string }; return ( <ConfigDetailContainer title="device.configTabs.LOCATION_HISTORY"> <LocationChild ref={locationChildRef} data="asdafaf"></LocationChild> <Button onClick={handleClick}>查看子组件的type的类型</Button> </ConfigDetailContainer> ); }
父组件中需要通过useRef来创建ref并传递给子组件,这样父子组件就建立了连接,父组件可以通过ref来访问子组件中自定义暴露的属性或方法。
这里的操作就是父组件点击按钮控制台打印子组件接收到的data这个prop的类型。
泛型参数
现在新的问题就是我们的父组件传递的data的类型不是固定的,这时候子组件就要将data的类型用泛型来定义,所以这里就有了fowardRef传递泛型参数的问题:
我们可以这样改造子组件,思路就是将这个组件改为工厂hansh的生成模式:
import { Box, Typography } from "@mui/material"; import { forwardRef, useImperativeHandle } from "react"; export interface LocationChildProps<T = string> { data: T; } export interface LocationChildRef { sayType(): void; } const LocationChild = function <T>() { return forwardRef<LocationChildRef, LocationChildProps<T>>((props, ref) => { useImperativeHandle(ref, () => ({ sayType() { console.log("子组件的data是 " + typeof props.data); }, })); return ( <Box> <Typography>{typeof props.data}</Typography> </Box> ); }); }; export default LocationChild;
然后在父组件中使用
import { Button } from "@mui/material"; import { PropsWithRef, useRef } from "react"; import ConfigDetailContainer from "../options/ConfigDetailContainer"; import LocationChild, { LocationChildProps, LocationChildRef } from "./LocationChild"; export default function DeviceLocation() { const locationChildRefString = useRef<LocationChildRef>(); const locationChildRefBoolean = useRef<LocationChildRef>(); const handleClick = () => { locationChildRefString.current.sayType(); locationChildRefBoolean.current.sayType(); }; const LocationChildComponent = LocationChild<string>(); const createComponent = function <T>(props: PropsWithRef<any>, ref: React.MutableRefObject<LocationChildRef>) { const Mycomponent = LocationChild<T>(); return <Mycomponent ref={ref} {...props}></Mycomponent>; }; return ( <ConfigDetailContainer title="device.configTabs.LOCATION_HISTORY"> <LocationChildComponent ref={locationChildRefString} data={"123"}></LocationChildComponent> {createComponent({ data: true }, locationChildRefBoolean)} <Button onClick={handleClick}>查看子组件的type的类型</Button> </ConfigDetailContainer> ); }
我们可以直接调用LocationChild方法生成组件,也可以再度封装为createComponent这样的方法,这样就实现了forwardRef中使用泛型参数的需求。
react forwardRef 导致 泛型丢失
网上没有找到合适的方案,看了 antd 的源码
实现方式如下
const ForwardTable = React.forwardRef(InternalTable) as <RecordType extends object = any>( props: React.PropsWithChildren<TableProps<RecordType>> & { ref?: React.Ref<HTMLDivElement> }, ) => React.ReactElement; // so u can use <Table<{id: string, b: number}> />
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
React Hooks使用startTransition与useTransition教程示例
这篇文章主要为大家介绍了React Hooks使用startTransition与useTransition教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-01-01react-native 父函数组件调用类子组件的方法(实例详解)
这篇文章主要介绍了react-native 父函数组件调用类子组件的方法,通过详细步骤介绍了React 函数式组件之父组件调用子组件的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-09-09react component changing uncontrolled in
这篇文章主要为大家介绍了react component changing uncontrolled input报错解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-12-12
最新评论