In this example here will be the mixed scenario. The parent component has states, and the child component. It's the mixed implementation. Of course, usually you make everything in the same style, but there are situations, when you need the mixed implementation.

Parent component (App.tsx)

import { useState } from 'react'
import './App.css'
import { LoginForm } from './Components/LoginForm/LoginForm'

function App() {
  const [currentLogin, setCurrentLogin] = useState('')
  const handleLogin = (log: string) => {
    // Update state would require a setter for currentLogin
    setCurrentLogin(log)
  }
  return (
    <>
        APP: {currentLogin}
        <br />
        <LoginForm onUpdate={handleLogin}  />    
    </>
  )
}

export default App

The Child component (LoginForm.tsx, class implemetation)

import * as React from 'react';
import type { AppProps } from '../../AppProps';

type State = {
  login: string, 
  password: string, 
};
export class LoginForm extends React.Component<AppProps, State>{
    state = {
        login: '', 
        password: ''
    }
    sendDataToParent = (login:string) => {
    this.props.onUpdate(login);
  };

    constructor(props:AppProps)  {
        super(props)
    }

  render() {
    return (
      <div>
        <input type='text' onChange={ (e: React.ChangeEvent<HTMLInputElement > ) => 
        {
            const login = e.currentTarget.value
            this.sendDataToParent(login)
        }
            } />
      </div>
    );
  };
};