Behnam Azimi
Behnam Azimi

Reputation: 2488

Optional forwardRef that is required inside - ReactJS

Here is my custom component with forwardRef. The ref is required in the component inside codes but it's optional for the parent component to send it as a prop

const MyComponent = React.forwardRef((props, ref) => {

    const handleButtonClick = () => {
        // I need to access the ref here but, it's null
        // when I not pass ref as prop to my component 
    }

    return (
        <>
            <input type="text" ref={ref}/>
            <button onClick={handleButtonClick}>Click</button>
        </>
    )
})

How should I handle this? I want to have an optional ref as a prop also it's required inside.

Also, I tried to use the useRef in my component and pass the forwarded ref as its initial value, in that case, I could not reach the ref in my parent component.

Upvotes: 5

Views: 6573

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281784

You can define a localRef using useRef in case the parent hasn't passed on a ref

const MyComponent = React.forwardRef((props, ref) => {
    const localRef = useRef(null);
    const inputRef = ref || localRef;
    const handleButtonClick = () => {
        // I need to access the ref here but, it's null
        // when I not pass ref as prop to my component 
        // access input using `inputRef.current`
    }

    return (
        <>
            <input type="text" ref={inputRef}/>
            <button onClick={handleButtonClick}>Click</button>
        </>
    )
})

However its a better practise to not use refs to access input values, instead make input as a controlled component and pass this information to parent via a props supplied by parent

const MyComponent = React.forwardRef((props, ref) => {
    const [value, setValue] = useState('')
    const handleButtonClick = () => {
        // access input value from state like
        console.log(value);
        props.handleSubmit && props.handleSubmit(value)
    }
    const handleChange = e => {
       setValue(e.target.value);
    }
    return (
        <>
            <input type="text" value={value} onChange={handleChange} ref={inputRef}/>
            <button onClick={handleButtonClick}>Click</button>
        </>
    )
})

Upvotes: 13

Related Questions