簡體   English   中英

帶有 forwardRef 的 JSX 點符號 typescript

[英]JSX dot notation with forwardRef typescript

我正在嘗試使用 forwardRef 找出 Dot Notation 組件的類型。

所以我發現這個例子完美地說明了我目前如何使用點符號,但不包括 forwardRef: https://codesandbox.io/s/stpkm

這就是我想要實現的目標,但無法弄清楚類型。

import { forwardRef, useImperativeHandle } from "react";
//
import { ForwardRefRenderFunction } from "react";

const TabToggle: React.FC = () => null;
const TabContent: React.FC = () => null;

interface TabsStatic {
  Toggle: typeof TabToggle;
  Content: typeof TabContent;
}

export interface TabsProps {
  initialIndex?: number;
}

export interface TabsRefMethods {
  show: () => null;
  hide: () => null;
}

export const Tabs: React.ForwardRefRenderFunction<
  TabsRefMethods,
  TabsProps & TabsStatic
> = forwardRef((props, ref) => {
  const openFn = () => null;
  const closeFn = () => null;
  useImperativeHandle(ref, () => ({ show: openFn, hide: closeFn }));
  return null;
});

Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

代碼沙盒演示https://codesandbox.io/s/jsx-dot-notation-in-typescript-with-react-forked-38e1z?file=/src/Tabs.tsx

我知道並使用了兩種可能的方法。 兩者的權衡略有不同。

第一個是插入 ( & ) static 組件並將它們標記為可選 ( Partial ) 以便在聲明組件時不會出錯。 缺點是它們被表示為可選的,即使它們總是被設置。

import * as React from "react";

const TabToggle: React.FC = () => null;
const TabContent: React.FC = () => null;

interface TabsStatic {
  Toggle: typeof TabToggle;
  Content: typeof TabContent;
}

export interface TabsProps {
  initialIndex?: number;
}

export interface TabsRefMethods {
  show: () => null;
  hide: () => null;
}

export const Tabs: React.ForwardRefExoticComponent<
  React.PropsWithoutRef<TabsProps> & React.RefAttributes<TabsRefMethods>
> &
  Partial<TabsStatic> = React.forwardRef((props, ref) => null);

Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

另一種方法是使它們成為必需的,但這需要強制轉換。 結果類型更准確,但它確實需要強制轉換。

type TabsComponent = React.ForwardRefExoticComponent<
  React.PropsWithoutRef<TabsProps> & React.RefAttributes<TabsRefMethods>
> &
  TabsStatic;

export const Tabs = React.forwardRef((props, ref) => null) as TabsComponent;

Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

有更簡單的方法可以達到相同的結果:

const Flex = React.forwardRef(function Flex(...) {
  ...
})

const FlexRow = React.forwardRef(...)
const FlexColumn = React.forwardRef(...)

const FlexNamespace = Object.assign(Flex, {Row: FlexRow, Column: FlexColumn})

export {FlexNamespace as Flex}

現在您可以在 TS 滿意的情況下使用FlexFlex.RowFlex.Column 魔術線是Object.assign不會導致與Flex.Row = FlexRow相同的類型問題。 不要問我為什么,我只是偶然發現了這個

或者更短:

const TabsComponent = () => {
  // implement the Tabs component
};

const TabContentComponent = () => {
  // implement the TabContent component
};

const TabToggleComponent = () => {
  // implement the TabToggle component
};

export const Tabs = Object.assign(forwardRef(TabsComponent),
  // a component with forward refs
  TabContent: forwardRef(TabContentComponent),

  // a component without forwarding
  TabToggle
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM