forwardRef در ری اکت چیست ؟ آموزش forwardRef در ریکت !
forwardRef در ری اکت به ما اجازه میده یک ref رو از کامپوننت والد به کامپوننت فرزند پاس بدیم ( منقل کنیم ). برای اینکه بدونیم forwardRef در ری اکت چیه و دقیقا چیکار میکنه باید قبلش بدونیم ref و هوک useRef تو ریکت چی هستن و چیکار میکنن. با فرانت اندی همراه باشید تا ببینیم forwardRef در react چیه ؟ 🙂
( تو مقاله useRef در ریکت در این رابطه صحبت کردیم، پیشنهاد میکنم مطالعه کنید )
اما بریم ببینیم forwardRef در ریکت چیه ؟
forwardRef در ری اکت چیست ؟
ما میدونیم که از ref در ری اکت میتونیم برای دسترسی به Element های موجود در DOM استفاده کنیم.
یعنی میتونیم به کمک هوک useRef یک ref بسازیم و هر زمان که لازم داشتیم به Element خودمون که تو DOM هست دسترسی داشته باشیم.
اما شرایطی رو در نظر بگیرید که نیاز داریم از کامپوننت والد، به یکی از Element های کامپوننت فرزند دسترسی داشته باشیم!
ما تو کامپوننت والد ref رو ساختیم و از کامپوننت فرزند هیچ دسترسی به این ref نداریم که بتونیم به یکی از اِلِمان های کامپوننت فرزند این ref رو اختصاص بدیم!
اینجاست که forwardRef در ریکت به ما کمک میکنه 🙂 چون به کمک این ویژگی میتونیم ref های خودمون رو از کامپوننت والد به کامپوننت فرزند منتقل کنیم ( پاس بدیم ) که به این پروسه React.forwardRef میگیم.
ref در ریکت چیه و چرا بهش نیاز داریم ؟
ref در ریکت به ما اجازه میده که به یک Element ( اِلِمان ) بصورت مستقیم تو DOM دسترسی داشته باشیم.
بطور کل به ref ها زمانی احتیاج پیدا میکنیم که :
- بخوایم یک متود رو در DOM صدا بزنیم ( مثل فوکوس کردن ، اسکرول کردن ، انتخاب کردن یک متن و .. )
- یک اسکریپت رو صدا بزنیم یا با برخی کتابخانه های انیمیشن کار کنیم
تو تیکه کد زیر، ما یک ref به Element خودمون ( div ) دادیم تا بتونیم زمانیکه وارد DOM شد بهش دسترسی داشته باشیم :
import { useRef, useEffect } from 'react'
export function Parent() {
const myRef = useRef() // ساخت رِِف
useEffect(() => {
// after mounting
console.log(myRef.current) // اینجا به اِلِمان خودمون که داخل دام هست دسترسی پیدا کردیم
}, [])
return سلاام من یه اِلِمانم. از داخل دام قابل دسترسی مستقیمم//اینجا رف خودمونو به این اِلِمان اختصاص دادیم
}
تو خط 4 یک ref ساختیم ( به کمک هوک useRef در react )
تو خط 11، ref ساخته شده رو به یک Element اختصاص دادیم ( که بتونیم زمانیکه وارد DOM شد بهش دسترسی داشته باشیم)
تو خط 8، زمانیکه کامپوننت و Element های ما وارد DOM شدن، به Element خودمون که یک div بود دسترسی پیدا کردیم و اِلِمان رو صرفا log گرفتیم ( اما هر کار دیگه ای میتونستیم باهاش بکنیم )
تو مثال بالا اصلا به forwardRef احتیاج پیدا نکردیم! اما بیاید سناریویی رو در نظر بگیریم که میخوایم به یکی از اِلِمان های کامپوننت فرزند در DOM دسترسی پیدا کنیم!
تو مثال زیر، ref خودمون رو در کامپوننت والد ساختیم و از طریق props به کامپوننت فرزند منتقل کردیم تا به div خودمون اختصاص بدیم :
import { useRef, useEffect } from 'react'
export function Parent() {
const myRef = useRef()
useEffect(() => {
// نمیتونیم دسترسی داشته باشیم !!
console.log(myRef.current) // Undefind!
}, [])
return // انتقال رِِف به کامپوننت فرزند
}
function Child({ ref }) { //یک کامپوننت جدید، که کامپوننت فرزند هست
return سلام
}
تو کد بالا از کامپوننت والد، یک ref رو به کامپوننت فرزند منتقل کردیم و به یک div اختصاص دادیم. اما زمانیکه میخوایم به اِلِمان div از کامپوننت والد دسترسی داشته باشیم به مشکل میخوریم!
در حقیقت خروجی خط 8، مقدار undefind هست!
در واقع کامپوننت والد، نمیتونه به اِلِمان div در کامپوننت فرزند که در DOM هست دسترسی داشته باشه ( با اینکه از ref استفاده کردیم)
ما ارور زیر رو از ری اکت دریافت میکنیم :
خود ری اکت فهمیده که ما میخوایم یک ref رو از کامپوننت والد به کامپوننت فرزند انتقال بدیم و بنده خدا پیشنهاد کرده از forwardRef استفاده کنیم 🙂
اتفاقی که تو تیکه کد بالا افتاد رو میشه تو تصویر زیر دید :
forwardRef در ریکت چیست ؟
forwardRef در ری اکت یک higher order Component در ری اکت هست که دور یک کامپوننت پیچیده میشه (Wrap میشه)
کامپوننتی که داخل forwardRef قرار میگیره ( Wrapped Component ) میتونه یک ref از کامپوننت والد دریافت کنه. به تصویر زیر دقت کنید :
پس بیاید به کمک forwardRef که یک HOC هست، ref خودمون رو از کامپونت والد به کامپوننت فرزند منتقل کنیم و به یک div در کامپوننت فرزند اختصاص بدیم:
import { useRef, useEffect, forwardRef } from 'react'
export function Parent() {
const myRef = useRef()
useEffect(() => {
// کار میکنه!
console.log(myRef.current) // خروجی : فرانت اندی
}, [])
return // انتقال رِِف به کامپوننت فرزند
}
const Child = forwardRef(function(props, ref) {
return فرانت اندی
})
تو تیکه کد بالا ما یک ref به اسم myRef ساختیم ( خط 4 ) و این ref رو به کامپوننت فرزند منتقل کردیم ( خط 11 )
تو کامپوننت فرزند ( که در خط 14 ساختیمش ) از forwardRef استفاده کردیم که یک higher order component هست. چون از forwardRef در ری اکت استفاده کردیم،تونستیم ref دریافت شده رو به div خودمون در کامپوننت فرزند اختصاص بدیم( خط 15 )
حالا از کامپوننت والد میتونیم به اِلِمان کامپوننت فرزند دسترسی داشته باشیم ( خط 8 )
اتفاقی که تو تیکه کد بالا افتاد رو میشه تو تصویر زیر دید :
forwardRef در تایپ اسکریپت !
ما میتونیم از forwardRef در تایپ اسکریپت هم استفاده کنیم اما یکم پیچیده تره! چون باید تایپ هارو مشخص کنیم.
درواقع forwardRef از ما دو آرگومان میگیره :
forwardRef()
- آرگومان V نوع مقداری هست که داخل ref میخوایم ذخیره کنیم. ( مثل div ) که معمولا مقدار HTMLDivElement یا HTMLInputElement رو بهش میدیم.
- آرگومان P نوع props کامپوننت فرزند هست.
حالا بریم مثال بالا رو با تایپ اسکریپت پیاده سازی کنیم :
import { useRef, forwardRef } from "react"
export function Parent() {
const myRef = useRef(null)
return
}
const Child = forwardRef(function (props, ref) {
return فرانت اندی
})
سعی کنید از ref تو ری اکت کمتر استفاده کنید!
قبل از هرچیز، لازمه یادآوری کنم که استفاده از ref خیلی جالب نیست و سعی کنید تا جایی که میشه از ref تو ری اکت استفاده نکنید.
چون ری اکت اومد که خودش DOM رو مدیریت کنه و کلی ابزار در اختیار ما گذاشت که نیاز نداشته باشیم مستقیما با DOM ارتباط بگیریم.
اگه مستقیما با DOM ارتباط بگیریم، هدف ری اکت رو نقض کردیم . البته گاهی اوغات لازمه که اینکار رو بکنیم.
جمع بندی
forwardRef در react به ما این امکان رو میده که از کامپوننت والد، به یکی از اِلِمان های کامپوننت فرزند دسترسی داشته باشیم ( دسترسی مستقیم در DOM )
بدون forwardRef نمیتونیم اینکار رو بکنیم.
در واقع forwardRef در ری اکت یک higher order component هست که دور کامپوننت فرزند پیچیده میشه ( wrap میشه )
امیدوارم که forwardRef در ریکت رو خیلی خیلی خوب متوجه شده باشید و ممنون که آموزش forwardRef در ری اکت رو در فرانت اندی مطالعه کردید 🙂
forwardRef در react به ما این امکان رو میده که از کامپوننت والد، به یکی از اِلِمان های کامپوننت فرزند دسترسی داشته باشیم ( دسترسی مستقیم در DOM )
در واقع forwardRef در ریکت یک higher order component یا همون HOC ( کامپوننت بالا مرتبه ) هست.
بله. تو این مقاله ( آموزش forwardRef در ری اکت ) درموردش صحبت کردیم.
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد10 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
عااالی بود ممنون
ممنون از توجهتون 🙂
مرسی بابت این مقاله کامل
برای من forwardRef در ری اکت جز اون مباحثی بود که هیچ جوره متوجهش نمیشدم و الان بعد مدت ها تونستم بفهممش ..
سلام و درود
خوشحالم که براتون مفید واقع شده 🙂
ممنون از توضیحاتتون
کامل و واضح
سلام خوشحالم که براتون مفید واقع شده 🙂
موفق باشی
ممنون بزرگوار .عالی
سلام و درود
قربانت زنده باشی
بسیار عالی. حالا در ری اکت 19 نیازی به forwardRef نداریم و میتونیم مستقیما ref را به child پاس بدیم.
قرباانت عماد جان، دقیقا همینطوره . البته هنوزم میتونیم ازش استفاده کنیم.