تزئین با React و TypeScript

سلام!
آیا مقاله پس از مقاله، پست پشت پست را جستجو کرده اید، و به دنبال راهی برای انتقال کامپوننت React به عنوان پشتوانه به کامپوننت دیگر بوده اید؟
من هم نه.
در واقع، فکر میکنم همه مقالههایی را که در اینترنت موجود است در رابطه با آن موضوع خواندهام… اما این چیزی نیست که دنبالش بودهام.
و این چیزی است که وقتی برای مواردی مانند موارد زیر جستجو میکنم ظاهر میشود:
- “ترکیب اجزای واکنش”
- “چگونه یک کامپوننت رندر نشده را به عنوان یک پایه ارسال کنیم تا بتوانم بعداً آن را رندر کنم”
- “نحوه اعمال props به کامپوننتی که به عنوان پروپوزال ارسال شده است”
- “یک کامپوننت را بهعنوان پایهها ارسال کنید و پایههای آن را بهعنوان پایهها ارسال کنید و آن کامپوننت را با آن قطعات در داخل کامپوننت دیگری رندر کنید.”
باید اضافه کنم که این همه باید در TypeScript انجام شود.
در اینجا شرح من از آنچه می خواستم انجام دهم است:
یک کامپوننت react ایجاد کنید که بتواند کامپوننت دیگری را به عنوان پروپوزال بپذیرد و سپس آن کامپوننت را در اطراف محتویات خود رندر کنید.
دلیلی که میخواهم این کار را انجام دهم این است که بتوانم یک کامپوننت ظرف (A) را در اطراف مولفه دیگر (B) بپیچم و به A اجازه دسترسی به وضعیت و پروپهای موجود در B را بدهم.
از آنچه من می فهمم، این شبیه به الگوی دکوراتور… یا فقط است آ الگوی دکوراتور…
معنی دارد؟
بیایید نگاه بیندازیم:
const Decorator = ({
title,
footer,
children,
}: PropsWithChildren<{ title: string; footer: string }>) => {
return (
<div>
<h1>{title}h1>
<div>{children}div>
<span>{footer}span>
div>
);
};
در بالا یک مؤلفه بسیار ساده داریم که نام آن را می گذاریم Decorator
. این جزءی است که من می خواهم از آن برای بسته بندی یا استفاده کنم تزئین کنید جزء دیگر
const Decorated = <T,>(props: {
Decorator?: ComponentType<T>;
decoratorProps?: T;
}) => {
const { Decorator, decoratorProps } = props;
const renderStuff = () => (
<div>
<h1>Decoratedh1>
div>
);
return Decorator ? (
<Decorator {...(decoratorProps)}>{renderStuff()}Decorator>
) : (
renderStuff()
);
};
این Decorated
کامپوننت در دو قسمت ظاهر می شود: Decorator
، یک جزء و decoratorProps
خواهد بود که لوازم جانبی از Decorator
جزء.
اگر در IDE خود هستید و کامپایلر TS در حال اجرا است، باید ببینید که مشکلی در نمونه سازی وجود دارد. Decorator
:
Type '{ children: Element; }' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to '{ children: Element; }'.typescript(2322)
من یک جادوگر TypeScript نیستم، اما به نظر من شبیه است Decorator
دیوانه است که بچه ها را می پذیرد یا چیزی. من قصد ندارم تمام تلاشهایی را که قبل از رسیدن به یک راهحل عملی انجام دادهام انجام دهم که این قانون را نادیده نمیگیرد، بلکه بدانید که تعداد زیادی از آنها وجود داشته است. چیزی که در نهایت به آن رسیدم این بود:
<Decorator {...(decoratorProps as T)}>{renderStuff()}Decorator>
تایپ کاست decoratorProps
به T
همه مشکلات من را حل می کند … خوب، نه همه آنها، اما به اندازه کافی برای من برای عبور از این کار است.
در اینجا یک نمونه از پیاده سازی است:
const Decorated = <T,>(props: {
Decorator?: ComponentType<T>;
decoratorProps?: T;
}) => {
const { Decorator, decoratorProps } = props;
const renderStuff = () => (
<div>
<h1>Decoratedh1>
div>
);
return Decorator ? (
<Decorator {...(decoratorProps as T)}>{renderStuff()}Decorator>
) : (
renderStuff()
);
};
const DecoratorOne = ({
title,
footer,
children,
}: PropsWithChildren<{ title: string; footer: string }>) => {
return (
<div>
<h1>{title}h1>
<div>{children}div>
<span>{footer}span>
div>
);
};
const DecoratorTwo = ({
title,
footer,
children,
article,
}: PropsWithChildren<{ title: string; footer: string; article: string }>) => {
return (
<div>
<h1>{title}h1>
<div>{children}div>
<div>{article}div>
<span>{footer}span>
div>
);
};
export default function App() {
return (
<div className="App">
<Decorated />
<Wrapper
Decorator={DecoratorOne}
decoratorProps={{
title: "DECORATOR ONE",
footer: "ONE FOOT",
}}
/>
<Wrapper
Decorator={DecoratorTwo}
decoratorProps={{
title: "DECORATOR TWO",
footer: "TWO FOOT",
article: "this is an article",
}}
/>
div>
);
}
و در اینجا پیوندی به جعبه شنی وجود دارد که می توانید در آن بازی کنید!
میدانم که به این موضوع نپرداختهام که چرا اتفاقات رخ میدهد، اما امیدوارم اگر شما، خواننده، اطلاعات یا اطلاعاتی برای به اشتراک گذاشتن دارید، خواهید داشت! در ضمن، در اینجا راهی برای پیاده سازی یک الگوی دکوراتور با React و Typescript ارائه شده است!