هنگامی که بر روی یک پروژه React کار میکنیم، احتمالاً تعریف یک تایپ برای React props رایجترین فعالیت تایپ اسکریپتی است که ما انجام خواهیم داد. بحثهایی در مورد بهترین روش برای تعریف props وجود دارد. در این مقاله قصد داریم تا مزایا و معایب هر روش را باهم بررسی کنیم.
سه روش برای تعریف props وجود دارد که در این بخش هر کدام را به شکل جداگانه بررسی میکنیم.
props را میتوانیم با استفاده از یک inline object تعریف کنیم.
import { ReactNode } from "react"; const Wrapper = (props: { children?: ReactNode; }) => { return <div>{props.children}</div>; };
تایپهای prop را میتوانیم destruct کرده و با سینتکس {}: {}
بنویسیم.
import { ReactNode } from "react"; const Wrapper = ({ children, }: { children?: ReactNode; }) => { return <div>{children}</div>; };
تایپهای Prop همچنین میتوانند به یک type alias نیز extract شوند:
import { ReactNode } from "react"; export type WrapperProps = { children?: ReactNode; }; const Wrapper = (props: WrapperProps) => { return <div>{props.children}</div>; };
Type aliaseها همیشه باید همراه با کامپوننت export شوند، به این ترتیب در صورت نیاز میتوانیم از آنها در فایلهای دیگر استفاده کنیم.
const Wrapper = ({ children }: WrapperProps) => { return <div>{children}</div>; };
Interfaceها راه دیگری برای تعریف props هستند:
import { ReactNode } from "react"; export interface WrapperProps { children?: ReactNode; } const Wrapper = (props: WrapperProps) => { return <div>{props.children}</div>; };
درست مانند type aliaseها، Interfaceها باید همیشه export شوند تا بعداً بتوانیم دوباره از آنها استفاده کنیم. همینطور میتوانیم Interfaceها همانند type aliaseها destruct کنیم.
const Wrapper = ({ children }: WrapperProps) => { return <div>{children}</div>; };
اکنون با همه روشها آشنا شدیم، اما قبل از تصمیمگیری نهایی بهتر است همه جوانب مثبت و منفی آنها را هم باهم بررسی کنیم.
مزیت اصلی تعریف props با استفاده از inline object سرعت بسیار بالای آن است. میتوانیم خیلی سریع props را تایپ کرده و به کدنویسی ادامه دهیم.
اما مشکلی که وجود دارد این است که inline objectها در نهایت باید به یک تایپ extract شوند. بنابراین اگر در حال نوشتن یک کامپوننت هستیم، احتمالاً باید از type aliase یا Interface استفاده کنیم. برای برطرف کردن این مشکل، توصیه میشود code snippet خود را برای type aliaseها و Interfaceها بنویسیم.
در ادامه یک code snippet داریم که برای ساختن کامپوننتهای خود در VSCode از آن استفاده میکنیم.
{ "component": { "prefix": "comp", "body": [ "export interface $1Props {", " $۲", "}", "", "export const $1 = (props: $1Props) => {", " return $3", "}" ] } }
تکمیل خودکار به comp
به یک کامپوننت با یک Interface توسعه پیدا میکند که هر دو export شدهاند.
به طور خلاصه، توصیه میشود که استفاده از type
aliasها ارجحیت بیشتری داشته باشد، زیرا ویژگی declaration merging در interface
میتواند برای مبتدیها کمی گیجکننده باشد.
اما یک مورد خاص وجود دارد که در بهتر است در این شرایط به جای type aliaseها از interfaceها استفاده کنیم. این مورد خاص ایجاد intersectionهای پیچیده از props است.
فرض کنید میخواهیم یک کامپوننت ایجاد کنیم که تمام props مربوط به input
را دارد اما نیاز به اضافه کردن یک label
props هست. ما باید از type helper به نام ComponentProps
extend پیدا کنیم.
استفاده از type
alias میتواند وسوسهانگیز باشد:
import { ComponentProps } from "react"; export type InputProps = ComponentProps<"input"> & { label: string; }; export function Input({ label, ...props }: InputProps) { return ( <label> {label} <input {...props} /> </label> ); }
اما متأسفانه intersectionهایی که از این طریق استفاده میشوند، در مقیاس یک پایگاه کد بزرگ سرعت تایپ اسکریپت را کاهش میدهند.
در عوض، باید از یک interface استفاده کنیم، با استفاده از interface extends
:
import { ComponentProps } from "react"; export interface InputProps extends ComponentProps<"input"> { label: string; }
این توصیه از ویکیپدیا عملکرد تایپ اسکریپت و همچنین یک PR از پایگاه کد Sentry است که با حذف این intersectionها به نفع interfaceها، بررسی تایپ آنها را تسریع میبخشد. بنابراین در شرایطی که تایپهای دیگر را extend میکنیم، بهتر است از interfaceها استفاده کنیم.
در این مقاله سعی کردیم تا روشهای مختلف تعریف props با تایپ اسکریپت را باهم بررسی کنیم. به طور کلی، ما برای تعریف props باید از interface
ها استفاده کنیم. آنها بیشترین عملکرد را دارند و با استفاده از یک code snippet، سریعتر نوشته میشوند.
اگر قبلاً برای تعریف props از inline objectها یا type
استفاده میکردیم جای نگرانی وجود ندارد. زیرا نیازی به refactor کردن پروژه نیست و برنامه به درستی کار میکند.
اما اگر احساس کردیم که در پایگاه کدی که داریم شروع به کند شدن سرعت در IDE کرده است، باید intersectionها را در props خود بررسی کنیم. اگر موردی را پیدا کردیم، سعی کنیم آنها را با interface extends
refactor کنیم.