Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I expose functions to the ref using functional components?

I want to create a component lets say a calendar functional component which can expose some functions like nextMonth, prevMonth, etc. So that the parent component using it can access these functions using the ref. It was easy with class components as the instance methods are automatically exposed. How do I achieve the same with functional components? I know I can use render props pattern for this. But any other solution?

Rough example:

function Calendar() {
   const nextMonth = () => {...}
   const prevMonth = () => {...}

   return (
      <div>.....</div>
   )
}


function Parent() {
   const cal = createRef();

   const onNext = () => {
     cal.current.nextMonth();
   }

   return (
     <>
        <Calendar ref={cal} />
        <button onClick={onNext}>Next</button>
     </>
   )
}

like image 497
mahadazad Avatar asked Aug 03 '19 09:08

mahadazad


1 Answers

You can use useImperativeHandle hook.

const Calendar = React.forwardRef((props, ref) => {
  const [month, setMonth] = useState(0)
  const nextMonth = () => { setMonth((prev) => prev + 1) }
  const prevMonth = () => { setMonth((prev) => prev - 1) }

  useImperativeHandle(ref, () => ({
    nextMonth,
    prevMonth
  }));

  return (
    <div>{month}</div>
  )
})

const Parent = () => {
  const cal = useRef()

  const onNext = () => {
    cal.current.nextMonth()
  }

  return (
    <React.Fragment>
      <Calendar ref={cal} />
      <button type="button" onClick={onNext}>Next</button>
    </React.Fragment>
  )
}
like image 70
Hamid Avatar answered Oct 08 '22 14:10

Hamid