reactjs - ما هو نوع خاصية 'children'؟
لدي عنصر وظيفي بسيط جدًا على النحو التالي:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
ومكون آخر:
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
ما زلت أتلقى الخطأ التالي:
[ts] نوع عنصر JSX 'ReactNode' ليس دالة منشئ لعناصر JSX. النوع 'undefined' لا يمكن تعيينه إلى نوع 'ElementClass'. [2605]
كيف أكتب هذا بشكل صحيح؟
الإجابة رقم 1
مجرد children: React.ReactNode.
الإجابة رقم 2
لكي تستخدم <Aux> في JSX الخاص بك، يجب أن تكون دالة تُرجع ReactElement<any> | null. هذه هي تعريف مكون الدالة.
ومع ذلك، فإنه يُعرف حالياً كدالة تُرجع React.ReactNode، وهو نوع أوسع بكثير. كما تقول تعريفات React:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
تأكد من تحييد الأنواع غير المرغوب فيها عن طريق تغليف القيمة المُرجعة داخل React Fragment (<></>):
const aux: React.FC<AuxProps> = props =>
<>{props.children}</>;
الإجابة رقم 3
يمكنك أيضًا استخدام React.PropsWithChildren<P>.
type ComponentWithChildProps = React.PropsWithChildren<{example?: string}>;
الإجابة رقم 4
يمكنك استخدام ReactChildren و ReactChild:
import React, { ReactChildren, ReactChild } from 'react';
interface AuxProps {
children: ReactChild | ReactChildren;
}
const Aux = ({ children }: AuxProps) => (<div>{children}</div>);
export default Aux;
إذا كنت بحاجة إلى تمرير مصفوفات مسطحة من العناصر:
interface AuxProps {
children: ReactChild | ReactChild[] | ReactChildren | ReactChildren[];
}
الإجابة رقم 5
هذا ما نجح معي:
interface Props {
children: JSX.Element[] | JSX.Element
}
تعديل أوصي باستخدام children: React.ReactNode الآن.
الإجابة رقم 6
العنصر React Node هو أحد الأنواع التالية:
Boolean(والذي يتم تجاهله)nullأوundefined(والذي يتم تجاهله)NumberString- عنصر
React(نتيجةJSX) - مصفوفة لأي مما سبق، وربما تكون متداخلة
الإجابة رقم 7
import { ReactNode, FC } from 'react'
type Props = { children: ReactNode }
const App: FC<Props> = ({children}) => (<div>{children}</div>)
الإجابة رقم 8
أنا أستخدم التالي
type Props = { children: React.ReactNode };
const MyComponent: React.FC<Props> = ({children}) => {
return (
<div>
{ children }
</div>
);
export default MyComponent;
الإجابة رقم 9
يمكنك إعلان مكونك هكذا:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
الإجابة رقم 10
نوع الإرجاع لمكون الدالة محدود بـ JSXElement | null في TypeScript. هذه قيود نوعية حالية، React النقي يسمح بأنواع إرجاع أكثر.
مقتطف عرضي بسيط
يمكنك إما استخدام تأكيد النوع أو المقاطع كحل بديل:
const Aux = (props: AuxProps) => <>props.children</>;
const Aux2 = (props: AuxProps) => props.children as ReactElement;
ReactNode
`children: React.ReactNode` قد يكون دون المستوى الأمثل، إذا كان الهدف هو الحصول على أنواع قوية لـ `Aux`.
يمكن تقريبًا تعيين أي شيء إلى نوع ReactNode الحالي، والذي يعادل {} | undefined | null. نوع أكثر أمانًا لحالتك قد يكون:
interface AuxProps {
children: ReactElement | ReactElement[]
}
مثال :
نظرًا لأن Aux يحتاج إلى عناصر React كـ children، فقد أضفنا عن طريق الخطأ string إليه. ثم ستحدث خطأ في الحل أعلاه على عكس ReactNode - ألق نظرة على الملاعب المرتبطة.
النوع children مفيد أيضًا للخصائص غير المتعلقة بـ JSX، مثل رد نداء Render Prop.
الإجابة رقم 11
الطريقة العامة للعثور على أي نوع هي عن طريق المثال. جمال TypeScript هو أن لديك الوصول إلى جميع الأنواع، طالما لديك ملفات @types/ الصحيحة.
للإجابة على هذا بنفسي، فكرت فقط في مكون يستخدمه React يحتوي على الخاصية children. أول شيء خطر في ذهني؟ ماذا عن <div />؟
كل ما تحتاج إلى فعله هو فتح vscode وإنشاء ملف .tsx جديد في مشروع react مع @types/react.
import React from 'react';
export default () => (
<div children={'test'} />
);
التحويم فوق الخاصية children يُظهر لك النوع. وماذا تعرف -- نوعه هو ReactNode (لا حاجة إلى ReactNode[]).
ثم إذا نقرت على تعريف النوع، فإنه يأخذك مباشرة إلى تعريف children القادم من واجهة DOMAttributes.
// node_modules/@types/react/index.d.ts
interface DOMAttributes<T> {
children?: ReactNode;
...
}
ملاحظة: يجب استخدام هذه العملية للعثور على أي نوع غير معروف! كلهم موجودون هناك فقط في انتظارك لتجدهم :)
الإجابة رقم 12
يمكنك أيضًا استخدام JSX.ElementChildrenAttribute
export default function Layout({children}: JSX.ElementChildrenAttribute) {
return <div>
{children}
</div>
}
