Reputation: 6348
I have an input that will be disabled by default, but at the click of a button I would like to simultaneously enable and focus the input.
I have attempted this in the same function, however it doesn't seem to work in my IDE/local react environment, and requires clicking the button twice to do this once will enable the input and the second will focus it... It is very strange to me
App.jsx
export const MyConstant = () => {
const [isDisabled, setIsDisabled] = useState(true);
const myInput = useRef();
const enableAndFocus = () => {
setIsDisabled(false);
myInput.current.focus();
}
return (
<button onClick={() => enableAndFocus()}>ClickMe</button>
<input ref={myInput} disabled={isDisabled} />
)
}
Here is a stackblitz of the issue
I can't understand why it won't do them together... Is it because the state change is slower than the focus?
Upvotes: 0
Views: 1160
Reputation: 819
You can have an useEffect
hook which is listening for the isDisabled
change and then you can focus on the input inside the hook if the isDisabled
is false.
export const MyConstant = () => {
const [isDisabled, setIsDisabled] = useState(true);
const myInput = useRef();
useEffect(() => {
!isDisabled && myInput.current.focus();
}, [isDisabled])
const enableAndFocus = () => {
setIsDisabled(false);
}
return (
<button onClick={() => enableAndFocus()}>ClickMe</button>
<input ref={myInput} disabled={isDisabled} />
)
}
Upvotes: 1
Reputation: 2635
setIsDisabled
is async function so when myInput.current.focus()
executes your input is still disabled.
To fix this try to use useEffect
hook like below:-
useEffect(() => {
if (!isDisabled) {
myInput.current.focus();
}
}, [isDisabled]);
Upvotes: 1
Reputation: 26390
I don't work with React, but I guess you can do a little trick like this, to allow React to "digest" the enabled state before focusing the input :
const enableAndFocus = async () => {
setIsDisabled(false);
await Promise.resolve();
myInput.current.focus();
}
Upvotes: 1