일반 상태 비저장 구성 요소 반응 유형?또는 일반 기능 인터페이스를 더 일반적이 되도록 타이프스크립트로 확장합니까?
문제:의 인터페이스Stateless Functional Component라고 되어
interface SFC<P = {}> {
(props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null;
propTypes?: ValidationMap<P>;
}
컴포넌트의 프로펠러 타입은 다음과 같습니다.
interface Prop<V>{
num: V;
}
컴포넌트를 적절하게 정의하는 방법다음과 같이 합니다.
const myCom: <T>SFC<Prop<T>> = <T>(props: Prop<T>)=> <div>test</div>
가 character 27 그그Cannot find name 'T'
다음은 Typescript Playground of modified example 입니다.
마이 파인딩:
1: Typescript 2.9.1 지원 스테이트풀 범용 컴포넌트
class myCom<T> extends React.Component<Prop<T>, any> {
render() {
return <div>test</div>;
}
}
내선2: 장SFC다음 답변에 언급된 것과 같이 새로운 인터페이스를 만드는 것은 구성 요소의 받침 유형을 다음과 같이 만들 것입니다.any: Typscript 원하지 않는 일반 파라미터/반환 타입으로 상태 비저장 함수 반응.내 소품에 적절한 활자를 주고 싶다.
제네릭스는 다음과 같이 사용할 수 없습니다.
const myCom: <T>SFC<Prop<T>> = <T>(props: Prop<T>)=> <div>test</div>
TypeScript 사양은 다음과 같습니다.
형상의 구성
< T > ( ... ) => { ... }형식 매개 변수가 있는 화살표 함수 식 또는 형식 매개 변수가 없는 화살표 함수에 적용되는 형식 어설션으로 구문 분석할 수 있습니다.
소스: Microsoft/TypeScript spec.md
선언이 TypeScript 사양에 정의된 패턴과 일치하지 않으므로 동작하지 않습니다.
단, SFC 인터페이스는 사용하지 않고 직접 선언할 수 있습니다.
interface Prop<V> {
num: V;
}
// normal function
function Abc<T extends string | number>(props: Prop<T>): React.ReactElement<Prop<T>> {
return <div />;
}
// const lambda function
const Abc: <T extends string | number>(p: Prop<T>) => React.ReactElement<Prop<T>> = (props) => {
return <div />
};
export default function App() {
return (
<React.Fragment>
<Abc<number> num={1} />
<Abc<string> num="abc" />
<Abc<string> num={1} /> // string expected but was number
</React.Fragment>
);
}
컴포넌트 외부에 범용 컴포넌트 타입의 에일리어스를 선언하고, 필요에 따라서 에일리어스를 아사트 하는 것으로, 이 문제를 경감하는 패턴이 있습니다.
예쁘지는 않지만 재사용이 가능하고 엄격합니다.
interface IMyComponentProps<T> {
name: string
type: T
}
// instead of inline with component assignment
type MyComponentI<T = any> = React.FC<IMyComponentProps<T>>
const MyComponent: MyComponentI = props => <p {...props}>Hello</p>
const TypedComponent = MyComponent as MyComponentI<number>
공장 패턴:
import React, { SFC } from 'react';
export interface GridProps<T = unknown> {
data: T[];
renderItem: (props: { item: T }) => React.ReactChild;
}
export const GridFactory = <T extends any>(): SFC<GridProps<T>> => () => {
return (
<div>
...
</div>
);
};
const Grid = GridFactory<string>();
업데이트: 2021년 3월 8일
후크 에러 규칙을 회피하려면 , 다음과 같은 구문을 미세하게 할 필요가 있습니다.
import React, { FC } from 'react';
export interface GridProps<T = unknown> {
data: T[]
renderItem: (props: { item: T }) => React.ReactChild
}
export const GridFactory = <T extends any>() => {
const Instance: FC<GridProps<T>> = (props) => {
const [state, setState] = useState(props.data)
return <div>...</div>
}
return Instance
}
const Grid = GridFactory<string>()
비슷하지만 약간 다른 해결책을 제안합니다(친구와 브레인스토밍).Formik 래퍼를 작성하려고 했는데, 다음과 같은 방법으로 작업을 할 수 있었습니다.
import React, { memo } from 'react';
export type FormDefaultProps<T> = {
initialValues: T;
onSubmit<T>(values: T, actions: FormikActions<T>): void;
validationSchema?: object;
};
// We extract React.PropsWithChildren from React.FunctionComponent or React.FC
function component<T>(props: React.PropsWithChildren<FormDefaultProps<T>>) {
// Do whatever you want with the props.
return(<div>{props.children}</div>
}
// the casting here is key. You can use as typeof component to
// create the typing automatically with the generic included..
export const FormDefault = memo(component) as typeof component;
그런 다음, 이렇게 사용합니다.
<FormDefault<PlanningCreateValues>
onSubmit={handleSubmit}
initialValues={PlanningCreateDefaultValues}
>
{/*Or any other child content in here */}
{pages[page]}
</FormDefault>
메서드 표현으로는 이 작업을 수행할 수 없습니다.
const a: React.FC<MyProp> = (prop) => (<>MyComponent</>);
@chris가 제시한 공장 패턴은 좋지만 리액트 훅을 사용할 수 없습니다.그래서 이걸 쓰고 있어요.
// Props
interface Props<T> {
a: T;
}
// Component
export const MyComponent: <T>(p: PropsWithChildren<Props<T>>) => React.ReactElement = props => {
return <div>Hello Typescript</div>;
};
자녀가 필요하지 않은 경우 Propos With Children 부품을 제거할 수 있습니다.소품 분해 및 후크도 작동합니다.
export const MyComponent: <T>(p: Props<T>) => React.ReactElement = ({ a }) => {
const [myState, setMyState] = useState(false);
return <div>Hello Typescript</div>;
};
방법이 있긴 한데 완벽한지 아닌지는 잘 모르겠어요.
interface ComponentProps<T> {
text: T;
}
export const Component= <T,>(props: ComponentProps<T>) => {
const { text } = props
const [s] = useState(0) // you can use hook
return (<div>yes</div>)
}
다음과 같이 컴포넌트를 사용할 수 있습니다.
(
<>
<Component<string> text="some text" />
</>
)
유형 정의에 React의 Function Component 유형을 포함하려면(예를 들어 반환 유형이 자동으로 선택되도록 하기 위해), 유형을 약간 반복해도 괜찮다면 다음과 같은 구성을 사용할 수 있습니다.
interface MyProps<T> {
val: T
}
const Component: React.FC<MyProps<any>> = <T>({
val
}: MyProps<T>) => {
// Your code and hooks here
return <div>Heya</div>
}
Const 유형Component이React.FC<MyProps<any>>즉, 이 값은 에 대해 유효한 값으로 사용할 수 있습니다.MyPropstype 파라미터T단, 구현에 의해 범용 타입 파라미터가 재지정되었기 때문에T구현 코드 내 타입은 다음과 같습니다.T가 아니라any이 때문에, 올바르게 타이프 체크됩니다. T다음과 같은 제한적인 지정자를 가질 수 있습니다.extends string인터페이스 사양과 기능 실장 시그니처 양쪽에서 이들 명령어를 반복하기만 하면 됩니다.
jmattheis 게시물에 따른 일반 상태 비저장 구성 요소의 예입니다.
MyGenericStatelessComponent.tsx
import React from "react";
type Prop<T> = {
example: T;
};
const MyGenericStatelessComponent: <T extends Record<string, number | string>>(props: Prop<T>) => JSX.Element = <
T extends Record<string, unknown>
>(
props: Prop<T>
): JSX.Element => {
return (
<div>
Example Prop id: {props.example.id}, Example Prop name: {props.example.name}
</div>
);
};
export default MyGenericStatelessComponent;
사용방법:
<MyGenericStatelessComponent example={{ id: 1, name: "test01" }} />
사용.T = any@vadistic의 예에서는 동작하지만 타입 체크는 할 수 없습니다.이 코드를 사용하면 코드 완성 및 입력 확인이 가능합니다.
interface IProps<TModel> extends RouteComponentProps {
headerText?: string | React.ReactNode;
collection: TModel[];
}
interface ICommonSortableType extends ISortableItem {
id: number;
isCorrectResponse: boolean;
}
interface ISortableItem {
sortableId: number;
}
type GenericFunctionalComponent<TModel> = React.FC<IProps<TModel>>;
const CommonSortableList: GenericFunctionalComponent<ICommonSortableType> = (props) => {
...
}
다음으로 다음과 같이 사용할 수 있습니다.
class CommonSortableType {
public sortableId: number = -1;
public id: number = -1;
public isCorrectResponse: boolean = false;
}
<CommonSortableList
collection={item.commonSortableTypes} //Is CommonSortableType[]
headerText={<FormattedMessage id="item.list" />}
</CommonSortableList>
class ExtendedOptionDto extends OptionDto implements ICommonSortableType {
public sortableId: number = -1;
}
class OptionDto {
public id: number = -1;
public isCorrectResponse: boolean = false;
}
<CommonSortableList
collection={item.extendedOptionDtos} //Is ExtendedOptionDto[]
headerText={<FormattedMessage id="item.list" />}
</CommonSortableList>
언급URL : https://stackoverflow.com/questions/51459971/type-of-generic-stateless-component-react-or-extending-generic-function-interfa
'source' 카테고리의 다른 글
| Reactjs가 초점을 맞출 때 입력되는 모든 텍스트를 선택하려면 어떻게 해야 합니까? (0) | 2023.02.22 |
|---|---|
| XMLHttpRequest에서 진행 상황을 가져오는 방법 (0) | 2023.02.22 |
| MUI 스타일로 소품 전달 (0) | 2023.02.18 |
| Typescript에서 오류를 발생시키는 함수를 선언하는 방법 (0) | 2023.02.16 |
| TypeScript에서 인터페이스 파일 정의를 기반으로 개체를 만들려면 어떻게 해야 합니까? (0) | 2023.02.16 |