@types/react
dan mengalami masalah.Definitions by:
di index.d.ts
) agar mereka dapat menanggapi.Komponen berikut
const SFC: React.StatelessComponent = (props) => props.children;
class C extends React.Component {
render() {
return this.props.children;
}
}
memberikan kesalahan
Type '(props: { children?: ReactNode; }) => ReactNode' is not assignable to type 'StatelessComponent<{}>'.
Type 'ReactNode' is not assignable to type 'ReactElement<any> | null'.
Type 'undefined' is not assignable to type 'ReactElement<any> | null'.
Class 'C' incorrectly extends base class 'Component<{}, {}>'.
Types of property 'render' are incompatible.
Type '() => ReactNode' is not assignable to type '() => false | Element | null'.
Type 'ReactNode' is not assignable to type 'false | Element | null'.
Type 'undefined' is not assignable to type 'false | Element | null'.
Ini berfungsi jika Anda membungkus children
dalam Element
.
Mengembalikan children
cukup umum ketika membuat komponen Provider yang hanya menambahkan sesuatu ke context
.
Saya mencoba perbaikan berikut untuk index.d.ts
- render(): JSX.Element | null | false;
+ render(): ReactNode;
- (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null;
+ (props: P & { children?: ReactNode }, context?: any): ReactNode;
tapi saya mendapatkan kesalahan di semua tempat saat mencoba lint yang saya tidak yakin bagaimana cara memperbaikinya.
TypeScript compile error: JSX element type 'ReactNode' is not a constructor function for JSX elements.
Tidak, perubahan ini tidak benar. Anda tidak dapat mengembalikan beberapa elemen di React saat ini. Bahkan jika Anda melakukannya di suatu tempat, kemungkinan besar itu dienkapsulasi dalam satu cara.
Hanya di React 16 dengan Fiber ini mungkin :)
tidak yakin apakah mereka mengubah perilaku reaksi, tetapi penulis redux/react memamerkan kemampuan untuk mengembalikan this.props.children untuk membuat pembungkus tipis (hanya untuk menambahkan childContext ke elemen), seperti yang terlihat di https://egghead.io/lessons/ javascript-redux-passing-the-store-down-implicitly-via-context
react-native memungkinkan Anda untuk mengembalikan array elemen JSX dari render. solusinya adalah membungkus this.props.children
dengan React.Children.only(this.props.children)
dan itu akan dibuang jika ada lebih dari satu elemen sebagai root
Benar, Anda dapat menggunakan React.Children.only
tetapi keduanya ReactNode
DAN ReactElement
adalah nilai yang valid dari this.props.children
.
const Title = props => <h1>{props.children}</h1>;
<Title>Woah</Title>
adalah kode React yang valid dan masuk akal.
Anda dapat mengembalikan array elemen dalam reaksi 16, tetapi TS membuat kesalahan karena menganggap Anda tidak bisa.
Sunting: lakukan ini children: JSX.Element[];
untuk memperbaikinya
Dari pengalaman saya sejauh ini, sepertinya ReactNode harus valid.
const Id: React.SFC<{}> = (props) => props.children
const App = ()= > <Id>This should work but instead fails</Id>
Apakah ada kemungkinan ini akan tercermin dalam @types/react
?
Tanpa ini saya tidak dapat mengetik React children
Saat ini saya membungkus children
dalam React.Fragment
untuk menyiasatinya.
Ada pembaruan di dalamnya?
Tidak yakin apakah ini lebih atau kurang benar daripada membungkus children
dalam React.Fragment
, tetapi saya beruntung melakukannya
return (children as React.ReactElement);
return <>{foo(}</>;
sepanjang malam. <>
adalah solusi.
Ini menyebabkan masalah bagi saya juga.
Saya memiliki HOC yang menambahkan alat peraga ke komponen tertentu, dan saya mencoba menggunakannya dengan komponen fungsional yang memiliki return children;
. Ini hanya berfungsi jika saya menggunakan solusi return <>{children}</>;
.
Berikut adalah versi sederhana dari HOC:
export interface ExtraProps {
extraProp1: string;
}
export const withExtraProps = <P extends object>(Component: React.ComponentType<P>) => {
return class extends React.Component<Omit<P, keyof ExtraProps>> {
render() {
const extraProps = {
extraProp1: 'test'
};
return (
<Component {...this.props as P} {...extraProps} />
)
}
}
}
Berikut adalah versi sederhana dari komponen fungsional:
interface ComponentProps extends ExtraProps {
children?: React.ReactNode;
loadingComponent?: ReactElement;
}
export function ExampleComponent(props: ComponentProps) {
const { children, loadingComponent } = props;
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
await someAsyncCall();
setLoading(false);
}
fetchData();
});
if (loading) {
return loadingComponent || null;
}
return children;
}
// This line errors:
export const FeatureFlag = withExtraProps(ExampleComponent);
Saya mendapatkan kesalahan berikut:
Argument of type '(props: ComponentProps) => {} | null | undefined' is not assignable to parameter of type 'ComponentType<ComponentProps>'.
Type '(props: ComponentProps) => {} | null | undefined' is not assignable to type 'FunctionComponent<ComponentProps>'.
Type '{} | null | undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
Type 'undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
Jika saya menambahkan tipe pengembalian ReactElement | null
ke ExampleComponent, ia berhenti mengeluh tentang meneruskannya ke HOC, tetapi masih error saat saya mengembalikan anak-anak:
export function ExampleComponent(props: ComponentProps): ReactElement | null {
...
...
return children; // Type 'ReactNode' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
}
Seperti yang lain di sini, jika saya mengubahnya menjadi return <>{children}</>;
, itu berfungsi, tetapi terasa kotor dan tidak perlu.
Saya memiliki _exact_ masalah yang sama dengan @kyrstenkelly - Fungsi HOC diteruskan React.FC
yang menjadikannya anak-anak.
Perbaikan <> children(...) </>
berfungsi, tetapi apakah ada solusi yang lebih baik?
Juga mengalami masalah ini! Saat ini sedang melakukan solusi yang disarankan untuk solusi pembungkus dengan React.Fragment
Sama disini
interface IIntlMessageProps {
id: string;
valuesGiven?: {[key:string]:string};
}
// this doesn't work - -- TS2769 Type 'null' is not assignable to type '(nodes:ReactNodeARray) => ReactNode' | ... | undefined
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
{props.children}
</FormattedMessage>
)
};
//Nope -- TS2769 Type 'Element' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
<React.Fragment>{props.children}</React.Fragment>
</FormattedMessage>
)
};
// Nope -- TS2769 Type 'Element' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> | null = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
<>{props.children}</>
</FormattedMessage>
)
};
// Nope -- TS2769 Type '{}' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
{props.children ? props.children : undefined}
</FormattedMessage>
)
};
Saya percaya saya telah mencoba semua yang disarankan di sini ... :( Ada petunjuk?
Solusinya adalah Anda perlu membungkusnya dalam fragmen.
import React from 'react'
const Something: React.FC = ({ children }) => (
<> { children } </>
)
ini akan memperbaiki kesalahan Type '({ children }: { children?: ReactNode; }) => ReactNode' is not assignable to type 'FunctionComponent
.
Jika memungkinkan, saya ingin menghindari fragmen dan membuat sistem tipe JSX mendukung jenis konstruksi yang sama yang didukung JavaScript dan Flow React, yang membantu TypeScript bekerja lebih baik dengan pola perpustakaan pihak ketiga.
Non-ideal lain yang saya temukan adalah bahwa fragmen memperdalam pohon komponen, terutama dalam komponen utilitas/pembungkus (case-in-point: react-placeholder). Mentransmisi ke React.ReactElement
sepertinya merupakan pendekatan yang lebih baik di perpustakaan semacam ini, tetapi saya lebih suka tidak perlu melakukan casting.
Saya mencoba pendekatan untuk mengubah tipe itu, tetapi macet dengan pemeriksaan tipe JSX menggunakan komponen fungsional tipe baru. Saya masih memiliki cabang, bisa bersumpah saya membuat PR meminta bantuan, tidak dapat menemukannya kembali ...
Oke, jika tipe perlu melarang array node, itu tidak berarti bahwa itu harus melarang ReactText
, ReactPortal
, boolean
, null
, dan undefined
juga apa kegunaan ReactElement
.
Apa alasan untuk melarang jenis tambahan ini?
Komentar yang paling membantu
Saat ini saya membungkus
children
dalamReact.Fragment
untuk menyiasatinya.