redexp
redexp

Reputation: 5065

React: how to set focus on last input after adding it?

can you please help me figure out how to set focus on last input after adding it by click on button?

function InputList() {
  const [items, setItems] = useState([]);
  const add = useCallback(() => setItems([...items, {id: uniqId()}]), [items]);

  return (
    <div>
      {items.map(item => <input key={item.id}/>)}
      <button onClick={add} type="button">Add</button>
    </div>
  );
}

Upvotes: 3

Views: 2233

Answers (2)

skyboyer
skyboyer

Reputation: 23705

easiest way is to pass the same ref to all the inputs:

const refToLast = React.createRef();
useEffect(() => {
  refToLast.current.focus();
});
...
      {items.map(item => <input ref={refToLast} key={item.id}/>)}
...

But we may found that we setting focus to last input on each re-rendering(even when we type some value). So we may add condition to set focus only when items.length is changed:

useEffect(() => {
  refToLast.current.focus();
}, [items.length]);

But that would also run when we remove entry not adding them. Not sure if that's desired.

[upd] to skip setting focus on initial rendering we can add additional flag:

const doSetAutoFocus = useRef(false);

useEffect(() => {
  refToLast.current.focus();
}, [items.length, doSetAutoFocus]);

const onAddClicked = useCallback(() => {
  add();
  doSetAutoFocus.current = true;
}, [add])

Upvotes: 3

ravibagul91
ravibagul91

Reputation: 20755

You can use autoFocus property and index (second argument of map) ,

{items.map((item,i) => <input key={item.id} autoFocus={i === items.length - 1 ? true : false}/>)}

Demo

Upvotes: 2

Related Questions