Calling Child Component Methods

Insofar as calling child component methods is concerned, using useImperativeHandle is identical to adding methods to a class component:

Class version — click the button to call the child's print() method via a ref.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head><body>
<div></div>
<script type="text/babel">
class Comp extends React.Component {
  print() {
    console.log('comp');
  }
  render() {
    return (<div>comp</div>)
  }
}
class App extends React.Component {
  constructor(props) {
    super(props);
    this.compRef = React.createRef();
  }
  render() {
    return (
      <React.Fragment>
        <button onClick={() => this.compRef.current.print()}>Call print()</button>
        <Comp ref={this.compRef}/>
      </React.Fragment>
    );
  }
}
const root = ReactDOM.createRoot(document.querySelector("div"));
root.render(<App/>);
</script>
</body></html>

is identical to:

Hook version — same behavior, using forwardRef and useImperativeHandle. (React 19 also lets you skip forwardRef entirely and receive 'ref' as a normal prop — see Exposing Selected Node Methods for that version.)
RESETRUNFULL
<!DOCTYPE html><html><head>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head><body>
<div></div>
<script type="text/babel">
const Comp = React.forwardRef((props, ref) => {
  React.useImperativeHandle(ref, () => ({
    print: () => {
      console.log('comp');
    }
  }), []);
  return <div>comp</div>;
});
function App() {
  const compRef = React.useRef(null);
  return (
    <React.Fragment>
      <button onClick={() => compRef.current.print()}>Call print()</button>
      <Comp ref={compRef}/>
    </React.Fragment>
  );
}
const root = ReactDOM.createRoot(document.querySelector("div"));
root.render(<App/>);
</script>
</body></html>

However, you should avoid calling methods of child components altogether as it is a bad practice.