reactjs - 如何使用 React 和 TypeScript 创建通用箭头函数

标签 reactjs typescript generics react-apollo react-functional-component

我正在尝试为 apollo graphql 结果创建一个通用包装组件。我希望这个包装器等待查询成功完成,然后渲染传递到 Prop 中的组件。传入的组件应该具有 QueryResult<T> 类型的 props .

这段代码片段在第 66 栏给了我一个错误:

Cannot find name 'T'.ts(2304)

import React from 'react';
import { QueryResult } from 'react-apollo';
import { useSandboxContext } from 'src/js/shared/components/SandboxContext';
import { ErrorContent } from 'src/js/shared/components/ErrorContent';
import { PageSpinner } from 'src/js/shared/components/PageSpinner';

interface WrapperComponentProps<T> extends QueryResult<T> {
  // TODO: figure out how to specify that the wrapped component takes the results
  // Something like this `React.ReactType<QueryResult<T>>` but this causes errors
  wrappedComponent: React.ReactType;
}

// Getting an error from `React.FC<WrapperComponentProps<T>>`
// `Cannot find name 'T'.ts(2304)`
export const ApolloResultWrapper: React.FC<WrapperComponentProps<T>> = <T extends object>(props: WrapperComponentProps<T>) => {
  const sandbox = useSandboxContext();

  if (props.error) {
    sandbox.logger.error('query failed', props.error);

    return <ErrorContent />
  }
  if (props.loading) {
    return <PageSpinner />;
  }

  if (!props.data) {
    return <ErrorContent />
  }

  // TODO: figure out how to spread all the props except wrappedComponent
  return <props.wrappedComponent {...props} wrappedComponent={undefined} />;
}

最佳答案

终于解决了这个问题

interface WrappedComponentProps<T> {
  data: T
}

interface WrapperComponentProps<T, K> {
  apolloResult: QueryResult<T>;
  wrappedComponent: React.ComponentType<WrappedComponentProps<T> & K>;
  componentProps: Omit<K, keyof WrappedComponentProps<T>>;
}

type ComponentProps<T, K> = React.PropsWithChildren<WrapperComponentProps<T, K>>;

export const ApolloResultWrapper = <T extends object, K = {}>(props: ComponentProps<T, K>) => {
  const sandbox = useSandboxContext();

  if (props.apolloResult.error) {
    sandbox.logger.error('stuff broke', props.apolloResult.error);

    return <ErrorContent />
  }
  if (props.apolloResult.loading) {
    return <PageSpinner />;
  }
  if (!props.apolloResult.data) {
    return <ErrorContent />
  }

  return <props.wrappedComponent
    children={props.children}
    data={props.apolloResult.data}
    {...props.componentProps as K}
  />;
}

关于reactjs - 如何使用 React 和 TypeScript 创建通用箭头函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61778548/

相关文章:

TypeScript 定义文件找不到 .d.ts

angular - Three.js + Angular : texture loading fails

java - JVM 实现之间的差异

c# - C# 中的通用返回类型

javascript - 在过滤方法 React/JS 中删除多个项目

javascript - 如何限制 Material-UI 的 TextField 组件中 String 字段的可能输入?

javascript - ReactJS 中 this.state 和 this.setstate 有什么区别?

javascript - React Router v4 将通过状态从搜索重定向到结果

typescript - 类方法不起作用 Angular 2 Typescript

c# - 通用存储库 - 表达式数组 <Func<T, TProperty>> 错误