Accessing another component’s DOM nodes
সাধারণত আমরা যখন কোন HTML ELEMENT
কে ref
দিয়ে ধরতে চাই, আমরা সেটা করতে পারি, এবং আমরা ref.current
এর মধ্যে তার ভ্যালুটা পাই। কিন্তু আমরা যদি আমদের কোন কাস্টম কম্পোনেন্ট (eg: <MyInput/>)
কে সরাসরি ধরতে চাই, তখন আমরা সেটা পারবোনা। এবং তখন যদি আমরা কনসলে ref
এর current
ভ্যালু দেখি আমরা তাতে null
পাবো।
চলুন একটা উদাহরণের মাধ্যমে এই প্রব্লেমটা বুঝা যাক,
import { useRef } from "react";
function MyInput(props) {
return <input {...props} />;
}
export default function MyForm() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<MyInput ref={inputRef} />
<button onClick={handleClick}>Focus the input</button>
</>
);
}
এখানে আমাদের দুইটা কম্পোনেন্ট আছে যার একটি হলো <MyInput/>
যাতে শুধুমাত্র একটি ইনপুট ট্যাগ আছে, আরেকটি হলো প্যারেন্ট কম্পোনেন্ট , এখানে একটি বাটন আছে এবং আমরা চাইছি এই বাটনে onClick
এ আমরা আমাদের যেই কাস্টম কম্পোনেন্ট <MyInput/>
এর ভিতরের ইনপুট ট্যাগ এ ফোকাস করবো। কিন্তু আমরা যদি এখন আউটপুট দেখি এবং বাটনে ক্লিক করি তাহলে দেখবো যে ইনপুট ট্যাগটা ফোকাস হচ্ছেনা।
তার কারণ হলো রিয়াক্ট বাই ডিফল্ট কোন কম্পোনেন্ট এর রেফারেন্স অন্য কম্পোনেন্টে শেয়ার করেনা এমনকি সেটা সেই কম্পোনেন্টের নিজের চাইল্ড কম্পোনেন্ট হলেও না।
কিন্তু আমরা যদি এই বিহেবিয়ারটাকে চেঞ্জ করতে চাই এবং সত্যিই চাই যে আমরা আমাদের কাস্টম কম্পোনেন্টের কোন Node কে আমরা বাহিরের কোন কম্পোনেন্টে এক্সেস দিবো তাহলে আমদেরকে সেই কাস্টম কম্পোনেন্টস থেকে রেফারেন্স টাকে ফরওয়ার্ড করে দিতে হবে React এর forwardRef
API ব্যাবহার করে।
সেজন্য আমাদের কে দুইটা স্টেপ ফলো করতে হবে।
প্যারেন্ট কম্পোনেন্ট থেকে ref
কে প্রপ্স এর মতো করে পাস করতে হবে ।
import { useRef } from "react";
export default function MyForm() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<MyInput ref={inputRef} />
<button onClick={handleClick}>Focus the input</button>
</>
);
}
চাইল্ড কম্পোনেন্ট থেকে কম্পোনেন্টটাকে forwardRef
(এটা একটা Higer Order Function) ব্যাবহার করে ref
সহ কম্পোনেন্ট কে ফরওয়ার্ড করে দিতে হবে।
এক্ষেত্রে আমরা আমাদের পুরো কম্পোনেন্ট টাকে forwardRef
দিয়ে wrap করে দিতে হবে এবং প্যারেন্ট কম্পোনেন্ট থেকে পাস করা ref
আমরা কম্পোনেন্টের সেকেন্ড প্যারামিটারে ধরতে পারি এবং সেটা কম্পোনেন্টের যেই নোডের এক্সেস চাই সেটাতে সেট করতে হবে।
import { forwordRef } from "react";
const MyInput = forwardRef((props,ref)=> { return <input {...props} ref={ref} />});
export default MyInput;
এবার যদি আমরা আউটপুট দেখি এবং বাটনে ক্লিক করি, আমরা দেখবো এটা কাজ করছে। স্বাভাবিক ভাবে কম্পোনেন্ট গুলো তাদের Node এর রেফারেন্স বাইরে শেয়ার করেনা কারণ এতে কম্পোনেন্ট আন-এক্সপেক্টেড আচরণ করতে পারে, তাই এটাই ডিফল্ট বিহেবিয়ার, আমরা এটাকে পরিবর্তন করতে চাইলে উপরের স্টেপগুলো ফলো করে করতে পারি।