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:
Why does when I focus/ type, at first, React outputs the correct classnames for
labelClassName inside
asformInput-label shrink
, but immediately changes it back toformInput-label
at thelabelClassName outside
position? How would I fix this?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}
/>
....