Home > Software engineering >  Reactjs. Use Ref inside the component and outside
Reactjs. Use Ref inside the component and outside

Time:01-08

I wrote a custom input for passwords. He looks like this:

const InputPassword = ({placeholder}) => {
    const inputRef = useRef()
    const [isPasswordVisible, setPasswordVisible] = useState(false)
  
    function setInputStatus() {
        if (isPasswordVisible) {
            inputRef.current.setAttribute('type', 'password')
        } else {
            inputRef.current.setAttribute('type', 'text')
        }
        setPasswordVisible(!isPasswordVisible)
    }

    return (
        <div className={cl.main}>
            <input
                ref={inputRef}
                type={"password"}
                placeholder={placeholder}
                className={cl.input}
            />
            <div className={cl.eyeContainer} onClick={setInputStatus}>
                <Eye
                    isPasswordVisible={isPasswordVisible}
                />
            </div>
        </div>
    );
};

export default InputPassword;

Now I want to get the value from my input in the parent component. The best way to do this is to use a forwardRef, but my component already has an internal Ref that is needed to change the type of the input. Surely you can somehow use one Ref to solve these two problems, but I did not find how.

I tried to pass a Boolean type state from the parent, so that when this state changes, call a method in the child component, this method would change another state in the parent, which stores the value from the child. And when this parent state changes, the necessary logic would work out for me. But the code turned out to be just as cumbersome and confusing as what is written above. Naturally, such code does not work well, it shows unpredictable behavior. I'm sure the solution is much simpler.

CodePudding user response:

You can also pass a state variable to the child component, I am passing a ref variable, assuming that the parent component does not need to re-render based on the changes in the value of variable that is being passed as a prop.

Your parent component should have a inputRef, and pass it as a prop to child component, something like this:

const Parent = () => {
  const inputRef = useRef()
  
  return <InputPassword inputRef={inputRef} />
}

export default Parent;


const InputPassword = ({placeholder, inputRef}) => {
    const [isPasswordVisible, setPasswordVisible] = useState(false)
  
    function setInputStatus() {
        if (isPasswordVisible) {
            inputRef.current.setAttribute('type', 'password')
        } else {
            inputRef.current.setAttribute('type', 'text')
        }
        setPasswordVisible(!isPasswordVisible)
    }

    return (
        <div className={cl.main}>
            <input
                ref={inputRef}
                type={"password"}
                placeholder={placeholder}
                className={cl.input}
            />
            <div className={cl.eyeContainer} onClick={setInputStatus}>
                <Eye
                    isPasswordVisible={isPasswordVisible}
                />
            </div>
        </div>
    );
};

export default InputPassword
  • Related