DEV Community

Simone Aronica
Simone Aronica

Posted on • Edited on

How do I get a subcomponent value while referring to the main component?

So I have a component containing an input, and I need to access the value of this input through the main component like this:

//component declaration:
<MDTextField label='Password' type='password' ref='passwordField'/>

//reffing:
this.refs.passwordField

Can I do this in the first place? And if I can, how do I do this?

Code

const MDTextField = props => {
    PropTypes.checkPropTypes(MDTextField.propTypes, props, 'prop', 'MDTextField');
    const [isFocused, setFocused] = useState(false);
    const [isEmpty, setEmpty] = useState(true);
    const error = props.error;
    const type = props.type.toLowerCase();
    if(!type.match(/^(email|text|password|search)$/))
        throw "Invalid type. Type must be either email, text, password or search."
    console.log('error: ' + error + 'focus: ' + isFocused);
    const _setFocus = () => {
        setFocused(true);
    };
    const _setUnfocus = () => {
        setFocused(false);
    };
    const _handleChange = e => {
        setEmpty(e.target.value.length > 0 ? false : true);
    };
    return (
        <div
        {...props}
        style={{borderColor: props.error ? "rgb(176, 0, 32)" : props.color && isFocused ? props.color : ""}}
        className={`${props.outlined ? style.MDTextFieldOutlined : style.MDTextField} ${props.outlined ? palette.MDTextFieldOutlined : palette.MDTextField} ${props.className ? props.className : ''}`}
        onFocus={_setFocus}
        onBlur={_setUnfocus}
        >
        <label
            className={`${style.Label} ${palette.Label}`}
            style={{
            color: error ? "rgb(176, 0, 32)" : props.accentColor && isFocused ? props.accentColor : "",
            transform: isEmpty ? "" : `translateY(-${props.outlined ? "50" : "50"}%) scale(.75)`
            }}
        >
            {(props.label ? props.label : '') + (error ? "*" : "")}
        </label>
        <span className={style.InputWrapper}>
            <input
            style={{caretColor: error ? "rgb(176, 0, 32)" : (props.accentColor ? props.accentColor : "")}}
            className={`${style.TextInput} ${palette.TextInput}`}
            onChange={_handleChange}
            type={type}
            />
        </span>
        </div>
    );
};

Top comments (5)

Collapse
 
manan30 profile image
Manan Joshi

The way to do it with refs is

  • declare a ref variable
    const fieldRef = React.useRef()

  • To access that ref use fieldRef.current

Collapse
 
itssimondev profile image
Simone Aronica

But this is inside the same component, but I want to access it through a ref in the main component, so outside of the component that is containing the input field

Collapse
 
manan30 profile image
Manan Joshi

You can do something like this

Main Component

function Main() {
    const ref = React.useRef();

    React.useEffect(() => {
        if (ref.current) {
          // Do something
        }
    });

    return <ChildComponent setRef = {ref}>
}

Child Component

function Child(props) {
    return <input ref={props.setRef} />
}
Thread Thread
 
itssimondev profile image
Simone Aronica • Edited

Ended up doing something I did not know the existence of and followed the react docs on this: reactjs.org/docs/forwarding-refs.h...

Thread Thread
 
manan30 profile image
Manan Joshi

Yup this is exactly what I was talking about.