[英]React 15, Typescript 2.2.1. How to cast types for functional/stateless components?
[英]How to specify (optional) default props with TypeScript for stateless, functional React components?
我正在嘗試在 Typescript 中創建一個帶有可選 props 和 defaultProps 的無狀態 React 組件(用於 React Native 項目)。 這對於 vanilla JS 來說是微不足道的,但我對如何在 TypeScript 中實現它感到困惑。
使用以下代碼:
import React, { Component } from 'react';
import { Text } from 'react-native';
interface TestProps {
title?: string,
name?: string
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (props = defaultProps) => (
<Text>
{props.title} {props.name}
</Text>
);
export default Test;
調用<Test title="Sir" name="Lancelot" />
會按預期呈現“Sir Lancelot”,但<Test />
應該輸出“Mr McGee”時什么結果都沒有。
任何幫助是極大的贊賞。
這是一個帶有答案的類似問題: React with TypeScript - 在無狀態函數中定義 defaultProps
import React, { Component } from 'react';
import { Text } from 'react-native';
interface TestProps {
title?: string,
name?: string
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test: React.SFC<TestProps> = (props) => (
<Text>
{props.title} {props.name}
</Text>
);
Test.defaultProps = defaultProps;
export default Test;
這是我喜歡這樣做的方式:
type TestProps = { foo: Foo } & DefaultProps
type DefaultProps = Partial<typeof defaultProps>
const defaultProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (props: Props) => {
props = {...defaultProps, ...props}
return (
<Text>
{props.title} {props.name}
</Text>
)
}
export default Test
將我的解決方案添加到鍋中,我認為它為現有解決方案增加了額外的可讀性和優雅度。
假設您有一個MyComponent
組件,其中包含必需和可選的 props。 我們可以將這些必需的和可選的 props 分成兩個接口,將它們組合起來作為組件的完整 prop 接口,但只使用可選的一個來設置默認的 props:
import * as React from "react";
// Required props
interface IMyComponentRequiredProps {
title: string;
}
// Optional props
interface IMyComponentOptionalProps {
color: string;
fontSize: number;
}
// Combine required and optional props to build the full prop interface
interface IMyComponentProps
extends IMyComponentRequiredProps,
IMyComponentOptionalProps {}
// Use the optional prop interface to define the default props
const defaultProps: IMyComponentOptionalProps = {
color: "red",
fontSize: 40,
};
// Use the full props within the actual component
const MyComponent = (props: IMyComponentProps) => {
const { title, color, fontSize } = props;
return <h1 style={{ color, fontSize }}>{title}</h1>;
};
// Be sure to set the default props
MyComponent.defaultProps = defaultProps;
export default MyComponent;
我可能是錯的,但是在函數上傳遞一個默認的 prop 值作為第二個投票的回復說可能會導致微妙的錯誤或過度執行 useEffects(我沒有足夠的代表來回復那里,所以這里有一個可重復的 codesanbox)
即使它是一個非常人為的例子,並且可能在大多數情況下只是糟糕的組件設計,我已經不止一次看到這種情況,甚至打破了整頁。
對於功能組件,確實有可能棄用defaultProps
字段。 我不相信這會很快發生,因為已經用它編寫了大量的代碼,但是很可能會在控制台中顯示警告。
我正在使用下面的解決方案,它提供了正確的行為和正確的 TypeScript 驗證。 它適用於混合定義/未定義的屬性,也適用於有/沒有默認值的屬性——也就是說,它涵蓋了所有情況:
interface Props {
name: string;
surname?: string;
age?: number;
}
const defaultProps = {
surname: 'Doe',
};
function MyComponent(propsIn: Props) {
const props = {...defaultProps, ...propsIn};
return <div>{props.surname}</div>;
}
VSCode 自動完成功能在:
它已經使用 TypeScript 4.7 進行了測試。
對我來說,這看起來不像是打字稿問題。
免責聲明:我只用打字稿試過這個。
然而,問題在於 props總是存在的(即使沒有傳入任何內容時作為空對象)。 不過,有兩種解決方法。
不幸的是,第一個會扼殺您擁有的超級干凈的無花括號語法,但讓我們保留defaultProps
。
interface TestProps {
title?: string;
name?: string;
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (passedIn: TestProps) => {
const props = Object.assign({}, defaultProps, passedIn);
return (
<p>
{props.title} {props.name}
</p>
);
}
如果您有大量道具,另一種選擇可能會有點麻煩,但這可以讓您保留原始語法,如下所示:
const Test = (props: TestProps) => (
<Text>
{props.title || 'Mr'} {props.name || 'McGee'}
</Text>
);
希望這有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.