Reactive Accelerator
React Js
React Escape Hatches
4.3 - Forwarding Refs : Accessing another component’s DOM nodes

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 এর রেফারেন্স বাইরে শেয়ার করেনা কারণ এতে কম্পোনেন্ট আন-এক্সপেক্টেড আচরণ করতে পারে, তাই এটাই ডিফল্ট বিহেবিয়ার, আমরা এটাকে পরিবর্তন করতে চাইলে উপরের স্টেপগুলো ফলো করে করতে পারি।