3

If I have a component like

const Comp = ({children}) => {

    //some code
    return (
        <div> 
            {children}
        </div>
    )

}

and then call it like

<Comp>
    <input onChange={...} />
    <input onChange={...} />
</Comp>

How can I change the focus to the first input field of this component when the component renders, from within the Comp component.

Ideally I would like to have a useEffect function or something which looks something like

useEffect(() => {
   thisComponent.firstChild.focus()
})
Sam
  • 1,765
  • 11
  • 82
  • 176
  • Check this one https://stackoverflow.com/questions/37647061/how-do-i-access-refs-of-a-child-component-in-the-parent-component – Wei Su Jun 13 '21 at 06:05
  • @ChrisSu That wont work because I can't set the ref to the children like that, because they are all passed in as `children` – Sam Jun 13 '21 at 06:10

1 Answers1

4

You need two things, useRef and useEffect, useRef for getting target element ref, and useEffect for handling focusing when then component renders.

children in a component props is an array, so you can manipulate it, you can use index to get which child element you want to set ref, and then call focus() by ref in useEffect:

function App(props) {
  const firstChildRef = useRef(null);

  useEffect(() => {
    if(firstChildRef.current) {
      firstChildRef.current.focus()
    }
  }, [firstChildRef])

  return (
    <div className="App">
      {props.children.map((child, index) => {
        if(index === 0) {
          return {...child, ref: firstChildRef};
        }
        return child;
      })}
    </div>
  );
}

Edit

Wei Su
  • 656
  • 4
  • 9
  • What if the first child isn’t focusable, like a label or something, or another div wrapper – Sam Jun 13 '21 at 06:55
  • @Sam You could do a conditional checking, if the method exists, call the method, otherwise do other things to handle the situation. – Wei Su Jun 13 '21 at 07:14
  • Im pretty sure that useEffect hook doesn't look safe listen to ref changes. So why the [firstChildRef]? – utopia Oct 24 '22 at 08:50