سلام :) امروز اومدم که شمارو با یه دیزاین پترن دیگه به اسم Provider آشنا کنم.
این پترن به شما شیوه ای راحت رو نشون میده که باهاش میتونین با استفاده از api هایی که react توی خودش جا داده دیتا رو از کامپوننت های پدر به فرزند به راحتی انتقال بدید و از props برای انتقال اون ها استفاده نکنید که بعدا به دردسر بیوفتید ( یکم جلوتر مشکل استفاده از props برای دیتا هایی که خیلی از کامپوننت ها نیاز دارنش رو نشون میدیم ) .
فرض کنید ما دیتایی مهم رو توی کامپوننت App دریافت میکنیم که کامپوننت های ListItem و Header و Text به اون نیاز دارن . برای این که بتونیم به این کامپوننت ها دیتای مورد نیازشون رو بدیم مجبوریم هستیم طبق ساختار درختی ای که توی کامپوننت ها داریم این دیتا رو از پدر به فرزند هاش اونقدر پاس بدیم تا به اون کامپوننتی که موردنظرمون هست دیتا برسه که نتیجش یه همچین چیزی میشه :
فکر کنم کم کم دارید میفهمید چه مشکلی داره درست میشه تو برناممون :)
داریم یه props رو الکی به یه کامپوننت میدیم چون فقط فرزندش نیازش داره که اینکار هم برناممون رو کثیف میکنه و هم اینکه اگر فردا قرار باشه یک دیتای دیگه هم به این شکل پاس بدیم کنترل کردن data flow برنامه خیلی سخت و غیرقابل توسعه میشه
برای حل این مشکل از Provider استفاده میکنیم که اگه از این طریق دیتاهامون رو انتقال بدیم دیگه لازم نیست کامپوننت پدر هی به بچه هاش props پاس بده
برای اینکار اول یک Context ایجاد میکنیم و کامپوننت هایی که میخواییم به بچه هاشون یه دیتایی برسه رو داخل Provider اون Context میریزیم :
همونطور که میبینید Provider ای که داریم یک props به اسم value میگیره که مقدار این props باید دقیقا برابر باشه با دیتایی که قراره کامپوننت های فرزند این Provider داشته باشن
برای این که توی کامپوننت هامون به مقدار این Context دسترسی داشته باشیم از هوک useContext به این شکل استفاده میکنیم :
و data flow برناممون به شکل زیر میشه که انصافا از قبلی خیلی تمیزتره :)
این پترن برای دیتاهای global ای که توی برنامه داریم بسیار مناسبه مثل هندل کردن تم های مختلف برای برناممون .
از این پترن توی کتابخونه های زیادی استفاده میشه که اگه بخواییم یکی از اونها رو مثال بزنیم میتونیم به styled-component اشاره کنیم که برای پیاده سازی تم هاش از همین پترن استفاده کرده:
توی این فایل اول میاییم یه Provider درست میکنیم به این شکل :
بعد میتونیم توی فایل های مختلف دیگمون از مقدار theme به این شکل استفاده کنیم :
فکر میکنم لازم نیست چیزی از فوایدش بگیم و مشخص باشه که چقدر دیتا فلوی برناممون رو مرتب میکنه و به راحتی میتونیم props هامون رو از کامپوننت های پدر به فرزند پاس داد و دیگه دردسر های قبل رو نداریم.
یکی از بزرگترین مشکلاتی که این پترن داره این هست که اگر دیتای Provider کامپوننتی که پدر هست تغییر بکنه تمامی کامپوننت های فرزند ( حتی اونایی که اصلا از دیتای Provider استفاده نکردن و ازش روحشونم خبر نداره re-render میشن و ممکنه توی برنامه های بزرگ مشکلات performance ای برامون داشته باشن.
برای همین ترجیح همیشه اینه که اگر میخوایید دیتایی رو داخل Provider بریزید سعی کنید اون دیتا انقدری مهم باشه و ارزش داشته باشه که همه ی کامپوننت های فرزند بخاطرش re-render بشن .
مثلا تم یکی از همون دیتا هاست که باید تمامی کامپوننت ها re-render بشن با عوض شدنش یا اگه پروژتون خیلی زیاد از این نوع دیتا های global داره میتونید از کتابخونه هایی که برای اینکار ساخته شدن مثل redux یا jotai استفاده کنین که دیگه لازم نیست دستی اینجور مسائل رو کنترل کنیم و تا حدودی کارمون رو راحت تر کردن
مرسی که وقت گذاشتید و این مطلب رو تا اینجا خوندید :) . امیدوارم براتون مفید بوده باشه
اگه متنی که نوشتم ایرادی داشت یا فکر میکنید با عوض کردن قسمتیش قابل فهم تر میشه ممنون میشم تو کامنت ها به من اعلام کنید.
من برای نوشتن این متن ها اول این سایت میرم و منطق یک دیزاین پترن رو میخونم و بعد چیز هایی که فهمیدم رو برای شما مینویسم مثلا تو پست قبلی راجب Proxy پترن توضیح دادم که میتونید رو لینک زیر کلیک کنید و بخونیدش