Reputation: 257
when i click on the focus button , i want to change the text inside the input box and then select it. But i have to click on the button twice to accomplish this task, that is, when i first click on the button , only the value is changed and when i click again, then the the text is selected
import { useRef, useState } from "react";
import "./styles.css";
export default function App() {
const [name, setName] = useState('')
const inputRef = useRef();
const editItem = () => {
setName('ray')
inputRef.current.select();
};
return (
<>
<input
ref={inputRef}
type="text"
value={name}
placeholder="e.g. eggs"
onChange={(e)=>setName(e.target.value)}
/>
<button type="button" className="edit-btn" onClick={editItem}>
Focus
</button>
</>
);
}
Upvotes: 2
Views: 1597
Reputation: 524
You can use useEffect hook to trigger the text selection. Toggle a focus
variable, whenever the focus button is clicked. So, on every click the text gets selected.
import { useEffect, useRef, useState } from "react";
import "./styles.css";
export default function App() {
const [name, setName] = useState("");
const [focus, setFocus] = useState(false);
const inputRef = useRef();
useEffect(() => {
inputRef.current.select();
}, [focus]);
const editItem = () => {
setName("ray");
setFocus(!focus);
};
return (
<>
<input
ref={inputRef}
type="text"
value={name}
placeholder="e.g. eggs"
onChange={(e) => setName(e.target.value)}
/>
<button type="button" className="edit-btn" onClick={editItem}>
Focus
</button>
</>
);
}
Upvotes: 2
Reputation: 329
setName()
is an asynchronous function which means when you first click the button inputRef.current.select();
is executed before setName()
is finished.
As a solution you can do:
const editItem = () => {
setName('ray')
};
useEffect(()=>
{
inputRef.current.select();
},[name]);
This calls inputRef.current.select()
as soon as setName()
changes the state.
Upvotes: 1
Reputation: 9294
You should useEffect
hook to select the text, because state changes in React are asynchronous. Try like this:
import { useRef, useState, useEffect } from "react";
import "./styles.css";
export default function App() {
const [name, setName] = useState("");
const inputRef = useRef();
const editItem = () => {
setName("ray");
};
useEffect(() => {
if (name === "ray") {
inputRef.current.select();
}
}, [name]);
return (
<>
<input
ref={inputRef}
type="text"
value={name}
placeholder="e.g. eggs"
onChange={(e) => setName(e.target.value)}
/>
<button type="button" className="edit-btn" onClick={editItem}>
Focus
</button>
</>
);
}
The useEffect
here executes everytime when name
state is changed and selects the text if it is ray
, because that's what button click sets it to.
To learn more about useEffect
, check this link.
Check this code working here.
Upvotes: 1