Home > Back-end >  How to change a class based on focus and change in an input form in React
How to change a class based on focus and change in an input form in React

Time:06-06

I have a situation where I want to append a class called shrink to the label text below (Display Name) when I click or type in the input box. My code is below:

const FormInput = ({ label, ...otherProps} ) => {
    let labelClassName = 'formInput-label';

    const addLabelClassName = () => {
        labelClassName = `${labelClassName} shrink`;
        console.log(labelClassName, 'labelClassName inside')
    }

    console.log(labelClassName, 'labelClassName outside')

    return (
        <div className="group">
            {label && 
                <label 
                    className={labelClassName}
                >{label}</label>
            }
            <input onFocus={addLabelClassName } onChange={addLabelClassName } className="formInput" {...otherProps} />
        </div>
    )
};

My question:

  1. Why does when I focus/ type, at first, React outputs the correct classnames for labelClassName inside as formInput-label shrink, but immediately changes it back to formInput-label at the labelClassName outside position? How would I fix this?

  2. I have also tried to change the code to using the UseState approach like below:

const FormInput = ({ label, ...otherProps} ) => {
    const [interaction, setInteraction] = useState('');
    let labelClassName = 'formInput-label';

    const onInteracting = () => {
        setInteraction('interacting')
    }

    if(interaction === 'interacting') {
        labelClassName = `${labelClassName} shrink`;
    }

    return (
        <div className="group">
            {label && 
                <label 
                    className={labelClassName}
                >{label}</label>
            }
            <input onFocus={onInteracting} onChange={onInteracting} className="formInput" {...otherProps} />
        </div>
    )
};

And this will append the correct class shrink to labelClassName but I'm not able to take that off when I click outside of the input/form. How may I fix this?

Thank you a ton!

CodePudding user response:

The second approach is a better way because with changing state you will trigger component rerendering (the first approach will never re-render component).

In the second approach, you can take advantage of onBlur event and create a handler which will set the state to the default value. Something like this. You don't need onChange to setIntercation

...
 const handleBlur = () => {
    setInteraction("");
  };
...

and then in input, you have to set up onBlur prop. onChange should not do the same thing as onFocus already does.

....
 <input
        onFocus={onInteracting}
        onBlur={handleBlur}
        className="formInput"
        {...otherProps}
      />
 ....

  • Related