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中使用泛型参数的需求。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Ref)和React.ForwardRefExoticComponent是什么? React.forwardRef()是一个用于在React组件之间传递refs的函数。它接受一个渲染函数作为参数,并返回一个新的组件,该组件可以将ref传递给其子组件。这个函数通常用于包装具有ref属性的DOM元素或其他React组件,以便在父组件中访问子组件的DOM节点或实例。 React.ForwardRefExoticComponent是一个泛型类型,用于定义接收ref组件类型。它接受一个类型参数,指定组件接受的props类型。通过使用这个类型,我们可以在编译时检查组件如何使用和传递ref。 在示例代码中,HtmlComponent是一个使用forwardRef()函数创建的组件,它是一个button元素。它接受props和ref作为参数,并返回一个button元素。这样,我们可以在父组件中使用ref属性引用这个button元素。 引用<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [react-frec:这是一个类型库,用于编写简单的“ React.forwardRef”和“ React.ForwardRefExoticComponent”](https://download.csdn.net/download/weixin_42157188/16743008)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Java在小程序开发方面的优势及应用](https://download.csdn.net/download/milk416666/88250412)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值