<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های sina.hoseinzadeh</title>
        <link>https://virgool.io/feed/@sina.hoseinzadeh</link>
        <description>برنامه نویس FrontEnd هستم.</description>
        <language>fa</language>
        <pubDate>2026-06-16 23:25:30</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/4472/avatar/SKyeep.png?height=120&amp;width=120</url>
            <title>sina.hoseinzadeh</title>
            <link>https://virgool.io/@sina.hoseinzadeh</link>
        </image>

                    <item>
                <title>پاس دادن props به props.children با استفاده از React.cloneElement</title>
                <link>https://virgool.io/@sina.hoseinzadeh/%D9%BE%D8%A7%D8%B3-%D8%AF%D8%A7%D8%AF%D9%86-props-%D8%A8%D9%87-propschildren-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-reactcloneelement-vfeyfloquspb</link>
                <description>ارتباط بین کامپوننت‌ها یکی از مهمترین و اولین گام در یادگیری ری‌اکت هست که تقریبا بعد از یه مدت کار کردن با این کتابخانه محبوب مثل دنده عوض کردن ماشین بدیهی و پیش پا افتاده میشه برامون. اما همیشه این ارتباط به این صورت سر راست و ساده نمیشه و ممکنه حالت های مختلفی از این ارتباط رو لازم داشته باشیم. در این مقاله سعی کردم در ابتدا حالت‌های مختلف ارتباط بین کامپوننت‌ها را مرور کنیم و ببینیم معمولا در چه مواردی میتونیم ازشون استفاده کنیم و در آخر به حالت مورد نظرمون یعنی با استفاده از React.cloneElement می‌پردازیم.روش اول – function as a childrenدر این روش فرزند به عنوان یک فانکشن به کامپوننت داده می شود و در نتیجه به عنوان آرگومان مقادیری همچون state کامپوننت والد را می توانیم به فرزند پاس بدیم. نمونه این مورد را احتمالا به هنگام استفاده از context  آنجایی که consumer  را فراخوانی می کنیم مشاهده کردیم و یا اگر با کتابخانه react transition group کار کرده باشید حتما با مثالی مشابه کدی که در زیر آوردم در داکیومنت این کتابخانه روبرو شدید:مثالی از function as childrenهمانطور که در تصویر میبینید ما به وسیله پارامتر state به state کامپوننت والد که یکی از موارد:  ‘entering’ , ‘entered’ , ‘exiting’ , ‘exited’ میتواند باشد دسترسی داریم.روش دوم – render propبرای اینکه چندین jsx مورد نظر رو در چند قسمت مشخص از کامپوننت والد رندر کنیم میتونیم از این روش استفاده کنیم. همچنین مقادیری از کامپوننت والد هم میتونیم به این jsx پاس بدیم.به کد زیر توجه کنید. برای مثال یه کامپوننت Card درست کردم که هر چیزی به عنوان children داخل Collapse رندر می شود و به عنوان هدر یه Button گذاشتم که در واقع در طراحی هدر دستمون بازه و هر چیزی میتونیم به Card  پاس بدیم.مثالی از render propالبته بهتره تا وقتی که دلیل خاصی ندارین، به جای پاس دادن فانکشن، یه کامپوننت پاس بدید. برای واضح‌تر شدن توضیحم به نمونه کد زیر دقت کنید.مثالی از Component as a propروش سوم – use React.cloneElementآخرین روشی که در این مقاله قصد داریم به آن بپردازیم، پاس دادن props به props.children با استفاده از React.cloneElement هست. معمولا کم پیش میاد ازش استفاده بشه اما روش باحالیه و کار رو برای استفاده از کامپوننت ها خیلی راحت می کنه. یادتون باشه که این با React.createElement فرق داره. createElement ، در واقع jsx توسط Babel کامپایل میشه به React.createElement. آبجکتی که ری اکت برای نمایش UI استفاده میکنه.اما cloneElement برای کلون کردن یه المنت و پاس دادن props جدید استفاده میشه.فرض کنید یه جایی از پروژه قصد داریم کامپوننت Tabs بسازیم که این کامپوننت قرار هست به تعداد مورد نیاز TabItem نمایش بده. خب چالش هایی که داریم  این خواهد بود که چطور بفهمیم روی کدوم TabItem کلیک شده.هر آیتم باید ایندکسی داشته باشه تا به عنوان currentItem در state قرار بگیرهدر هر بار استفاده ممکنه آیتم ها استایل متفاوتی داشته باشند، پس هر آیتم نیاز به className داره.بعدا هم مورد دیگه ای به ذهنمون برسه باید به تک تک آیتم ها اضافه بشه.خب از اونجایی که ما نمیدونیم children قراره چی باشه و هربار این همه مورد رو به آیتم ها اضافه نکینم بهتره که با کامپوننت والد یعنی همون Tabs طرف حساب بشیم. بریم سراغ کد و  ساختن کامپوننت TabItem :خب کامپوننت TabItem رو آماده کردیم که قراره به عنوان فرزند کامپوننت Tabs ازش استفاده کنیم. من برای ui از کتابخانه Material ui استفاده می کنم به همین خاطر استایل ها اینجا به صورت css-in-js هست و از makeStyles متریال استفاده شده. حالا میریم سراغ کامپوننت Tabs:مهمترین بخش این کامپوننت دریافت آرایه children و ساختن آرایه جدیدی از آن با props مد نظر است که به وسیله React.Children.map این کار رو انجام دادیم و هر آیتم توسط React.cloneElement کلون و آبجکتی با props مدنظر ایجاد میشه.من در این کامپوننت از state داخلی هم استفاده کردم که در صورت undefined بودن مقدار  مقادیر state داخلی مورد استفاده قرار بگیره.حالا خیلی تمیز و خلاصه میتونیم از کامپوننتمون استفاده کنیم.همینطور که دیدید تمامی props مورد نیاز TabItem را به کامپوننت Tabs پاس دادیم که این خیلی کار ما رو در هر بار استفاده راحت می کنه و در عین حال خوانایی بهتری هم داره.TabItem with parent propsامیدوارم که این آموزش داخل پروژه هاتون به کار بیاد و تونسته باشه گره ای از مشکلاتتون رو باز کنه. شاید دوستانی هم داشته باشید که دنبال چنین راه حلی باشند، لطفا به اون ها هم معرفی کنید. سوالی هم اگه داشتین میتونین در کامنت بپرسین، سعی میکنم در زودترین زمان ممکن جواب بدم.</description>
                <category>sina.hoseinzadeh</category>
                <author>sina.hoseinzadeh</author>
                <pubDate>Fri, 26 Feb 2021 00:01:02 +0330</pubDate>
            </item>
                    <item>
                <title>پیاده سازی svg introduction در react-native</title>
                <link>https://virgool.io/@sina.hoseinzadeh/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-svg-introduction-%D8%AF%D8%B1-react-native-ge01dyvhxkum</link>
                <description>خب تقریبا به کارهای پایانی توسعه محصول رسیدین و همه چی ایشالا مثل ساعت داره دقیق کار میکنه (هر چی باگ هم هست مال تیم قبلیه) و با ui دلبرانه دارین آماده میشین که مارکت رو تصاحب کنید. اما ممکنه امکانات اپ شما برای ورژن اول زیاد شده باشه و در دموی اول میبینین که به کاربراتون دارین از اون اول توضیح میدین که چیکار کنند و این کمی نگرانتون می کنه. یا اصلا نگران این هستین مخاطب ندونه از کجا باید شروع کنه و هر اصطلاح داخل اپ شما چه معنی میده.یکی از کارهایی که میشه انجام داد اینه که برای screen های مورد نظر برنامه تون intro بذارین. این کار رو هم میتونین به شکل اسلایدر های توضیحی توام با عکس انجام بدین (که احتمالا نمونه اش رو زیاد دیدین) و هم اینکه روی اسکرین اپ دکمه ها رو هایلایت کنین و به کاربر بگین با زدن این دکمه چنین کاری رو میتونه انجام بده. ما هم از این قاعده مستثنی نبودیم و یکی از چالش های جالبی که برای اپلیکیشن ejob داشتیم پیاده سازی همین introduction بود که قسمت هایی از اون رو در عکس زیر می بینید. در این مقاله میخوایم یاد بگیریم چطوری چیزی شبیه به این عکس بسازیم. سعی کردم نکات مهمی رو که خودم باهاشون سر و کله زدم رو به صورت خلاصه بنویسم.نتیجه همین کار که برای اپلیکیشن ایجاب انجام دادمتعریف پروژه و نصب پکیج های مورد نیاز:یه پروژه react-native تعریف می کنیم.npx react-native init introductionنیاز داریم با svg هم کار کنیم:yarn add react-native-svgیه اسکرین داریم که به شکل زیر هستش:صفحه ای که در نظر داریم براش آموزش بذاریم. خب این صفحه رو من داخل app.js ساختم که یه همچین کدی داره:کد صفحه appساختن کامپوننت Introduction:خب تا اینجای کار یه اسکرین تست درست کردیم و حالا میخوایم به کاربر توضیح بدیم هر کدوم از دکمه ها چه کار میکنه. فرض کنید برای دکمه های filter و post میخوایم یه intro بسازیم. یه کامپوننت میسازم به نام Introduction که شامل یه Modal خواهد بود که المنت های ما رو به شکل هایلایت معرفی میکنه.کد کامپوننت Introductionخب ما دو تا props برای این کامپوننت داریم:اولی elements هست که یک array از object ها هست که جلوتر میبینید که شامل چه property هایی هستند. دومی dismiss هست که یک فانکشنی هست برای بستن نمایش intro که از کامپوننت والد بهش میفرستیم.نکته مهم که حتما modal باید transparent باشه.یه state به نام current دارم که ازش برای مشخص کردن المنت فعلی که نمایش میده استفاده می کنم. یه دکمه داریم که منطق onPress اون به این شکل هست: اگه المنت فعلی آخرین المنت باشه از آرایه elements باید modal بسته بشه، در غیر این صورت یدونه به مقدار current اضافه میکنم تا بره به المنت بعدی.در رابطه با تگ های svg بخوام توضیح بدم این پست طولانی میشه و به همین دلیل فقط چند نکته مهم راجع بهش میگم. تگ defs به صورت مستقیم render نمیشه، تگ های svg که داخلش تعریف کنین نگه میداره و بعدا میتونین با رفرنس دادن بهشون ازشون استفاده کنید. تگ mask هم برای ترکیب آبجکتی که میخوایم با بک گراند لازم داریم. تگ ماسک داخلش دو تا تگ rect تعریف شده که یکی با fill سفید و اون یکی سیاه هست. کار fill سفید این هست که بک گراند ما رو که اینجا همون LinearGradient هست رو به خودش بگیره و fill سیاه اون بخش از بک گراند رو تو خالی نمایش میده. (شبیه همون چیزی که توی فتوشاپ هم داریم.)اما سوال اینجاست که اندازه اون المنت ها و محل نمایششون در صفحه رو از کجا بیاریم؟ برگردیم توی کامپوننت اپ و اون هم ببینیم.محاسبه موقعیت المنت های مد نظر در صفحه:کامپوننت اپ رو یه سری تغییرات انجام میدیم و کد نهاییمون به شکل زیر خواهد بود. دو تا state داریم. items آبجکتی از مقادیر اندازه ی المنت های مورد نظر و showIntro که برای شرط نمایش Introduction از اون استفاده می کنم.نکته: در مواقعی که رندر کردن کامپوننت Introduction بدون شرط باشه ممکنه اپ شما کرش کنه. چون رندر انجام شده اما مقادیر داخل تگ های svg شامل محل قرارگیری المنت به svg نرسیده. پس بهتره همیشه این موضوع رو به هر شکلی که راحتین کنترلش کنید.برای به دست آورن محل قرارگیری المنت مد نظر، UIManager و findNodeHandler رو از react-native ایمپورت می کنیم. متد measure رو فراخوانی می کنیم و findeNodeHandler را با ورودی ref المنت مورد نظر و همچنین یه callback به متد measure پاس میدهیم.همچنان برای خلاصه نوشتن این قسمت میتونین فانکشن onLayout را به این صورت نیز بنویسید:onLayout={() =&gt; {
postRef.current.measure((x, y, width, height, pageX, pageY) =&gt; {
setItems(prevState =&gt; ({ ...prevState, post: { x, y, width, height, pageX, pageY } }));
})بعد از به دست آوردن مقادیر مد نظر حالا وقتشه که کامپوننت Introduction رو رندر کنیم. داخل هوک useEffect که به items وابسته است شرطی گذاشتم که اگه طول items برابر با 2 بود (یعنی مقدار موقعیت هر دو المنت در صفحه محاسبه شده است)، وضعیت showIntro تغییر کند.خب همه چی سر جاش قرار داره و میریم اپ رو refresh میکنم. نتیجه نهایی به شکل زیر است: نتیجه نهاییامیدوارم که این آموزش داخل پروژه هاتون به کار بیاد و تونسته باشه گره ای از مشکلاتتون رو باز کنه. شاید دوستانی هم داشته باشید که دنبال چنین راه حلی باشند، لطفا به اون ها هم معرفی کنید. سوالی هم اگه داشتین میتونین در کامنت بپرسین، سعی میکنم در زودترین زمان ممکن جواب بدم.</description>
                <category>sina.hoseinzadeh</category>
                <author>sina.hoseinzadeh</author>
                <pubDate>Sat, 08 Aug 2020 15:31:36 +0430</pubDate>
            </item>
            </channel>
</rss>