Как передать функцию из child в parent компонент?

У меня есть компонент PassportForm, в котором я рендерю компонент Form. В компоненте Form у меня есть функция Register они из react hook form, но вряд ли это важно, проще говоря у меня есть компонент родителя и дочерний компонент, в дочернем есть функция, а вызывать её нужно в родительском компоненте, я что-то подзабыл как работают коллбэки, подскажите как написать, чтобы функция register работала в родительском компоненте?

const PassportForm = (): JSX.Element => {
  return (
    <Form
      depart={depart}
      toolName={PLASMID_PASSPORT}
      fields={fields}
      files={files}
      createConfig={createConfig}
      onFilesSubmit={onFilesSubmit}
      sharepointPaths={sharepointPaths}
    />
  );

}

const Form = ({
  depart,
  toolName,
  fields,
  files,
  createConfig,
  onFilesSubmit,
  handleSpChange,
}: Props): JSX.Element => {
  const {
    register,
    handleSubmit,
    formState: { errors, isValid },
    trigger,
  } = useForm({
    mode: 'all',
  });
}

Ответы (3 шт):

Автор решения: EzioMercer

Ну вообще лучше бы это делать с помощью контекста, но если прям именно хотите передать ф-ию наверх, то вам у родителя надо иметь ф-ию, которая на вход будет принимать то что вам надо

Примерно что-то такое должно быть:

const {useState} = React;

const Counter = ({setClick}) => {
  const [count, setCount] = useState(0);
  
  React.useEffect(() => {
    setClick(() => () => setCount((c) => c + 1));
  }, [])

  return <button>You clicked me {count} time(s)</button>
}

const App = () => {
  const [click, setClick] = useState(null);
  
  React.useEffect(() => {    
    if (click) {
      click();
      click();
      click();
      click();
    }

  }, [click])

  return <Counter setClick={setClick} />;
}

// Рендеринг
ReactDOM.render(
  <App />,
  document.getElementById('react')
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>

→ Ссылка
Автор решения: Alexander

Вызывать хук в родительском компоненте, прокидывать функцию register через пропсы или глобальный стейт.

  const PassportForm = (): JSX.Element => {
  const [state, setState] = useState()

  useEffect((
   console.log(state)
  )=>{},[state])

  return (
    <Form
      depart={depart}
      toolName={PLASMID_PASSPORT}
      fields={fields}
      files={files}
      createConfig={createConfig}
      onFilesSubmit={onFilesSubmit}
      sharepointPaths={sharepointPaths}
      setState={setState}
    />
  );

А в дочернем компоненте

        const Form = ({
      depart,
      toolName,
      fields,
      files,
      createConfig,
      onFilesSubmit,
      handleSpChange,
    }: Props): JSX.Element => {
      const {
        register,
        handleSubmit,
        formState: { errors, isValid },
        trigger,
      } = useForm({
        mode: 'all',
      });
    setState(register)
}
→ Ссылка
Автор решения: Абдулазиз

Я бы поступил так, вытащил бы все дочерние "state"ы в родительскую и через пропс передал бы. И функцию можно спокойно вызвать в родительском компоненте

function Parent() {
  const [username, setUsername] = useState("")
  const [password, setPassword] = useState("")

  const handleSubmit = e => {
     // ваша логика
  }

  return (
    <Child 
      username={username}
      password={password}
      handelSubmit={handleSubmit}
    />
  )
}

const Child = (({props}) => {

  return (
      <div>
        Username:
        <input
          value={props.username}
          onChange={e => props.setUsername(e.target.value)}
        />
      </div>
      <div>
        Пароль:
        <input
        value={props.password}
        onChange={e => props.setPassword(e.target.value)}
      />
      </div>
      <button
        onClick={() => props.handleSubmit()}
      >
        Register
      </button>
    )
})
→ Ссылка