React - useRef с TypeScript и функциональным компонентом


Я пытался вызвать метод дочернего компонента из родительского компонента, и я пытался использовать useRef. В будущем метод SayHi будет обновлять состояние перехвата в дочернем компоненте. К сожалению, у меня есть ошибки, с которыми я не могу справиться.

Строка: ref.current.SayHi ();

Свойство SayHi не существует для типа ForwardRefExoticComponent ‹{name: string; } & RefAttributes ‹{SayHi: () => void; } >> '.

Строка: ‹Child name =" Adam "ref = {ref} />

Тип RefObject void; } >>> 'нельзя присвоить типу' ((instance: {SayHi: () => void;} | null) => void) | RefObject ‹{SayHi: () => void; }> | null | неопределенный'. Тип RefObject void; } >>> 'нельзя присвоить типу' RefObject ‹{SayHi: () => void; }> '. Свойство SayHi отсутствует в типе ForwardRefExoticComponent ‹{name: string; } & RefAttributes ‹{SayHi: () => void; } >> 'но обязательно в типе' {SayHi: () => void; } '.


Полный файл test.tsx:

import React, { useRef, forwardRef, useImperativeHandle, Ref } from 'react'

const Parent = () => {
    const ref = useRef<typeof Child>(null);
    const onButtonClick = () => {
      if (ref.current) {
        ref.current.SayHi();
      }
    };
    return (
      <div>
        <Child name="Adam" ref={ref}/>
        <button onClick={onButtonClick}>Log console</button>
      </div>
    );
  }

const Child = forwardRef((props: {name: string}, ref: Ref<{SayHi: () => void}>)=> {
  const {name} = props;
  useImperativeHandle(ref, () => ({ SayHi }));

  function SayHi() { console.log("Hello " + name); }

  return <div>{name}</div>;
});

Я очень прошу помощи по этой теме.


person Adam Nowicki    schedule 05.03.2020    source источник


Ответы (2)


Вам необходимо извлечь тип ссылки в другом месте:

interface RefObject {
  SayHi: () => void
}

тогда просто обратитесь к нему в обоих местах

const Child = forwardRef((props: {name: string}, ref: Ref<RefObject>)=> {
  const {name} = props;  
  useImperativeHandle(ref, () => ({ SayHi }));
  function SayHi() { console.log("Hello " + name); }

  return <div>{name}</div>;
});
const Parent = () => {
    const ref = useRef<RefObject>(null);
    const onButtonClick = () => {
      if (ref.current) {
        ref.current.SayHi();
      }
    };
    return (
      <div>
        <Child name="Adam" ref={ref}/>
        <button onClick={onButtonClick}>Log console</button>
      </div>
    );
}
person Federkun    schedule 05.03.2020
comment
Большое спасибо! :) - person Adam Nowicki; 06.03.2020

Просто замените объявление вашего ref этим const ref = useRef<{ SayHi: () => void }>(null);

person giotskhada    schedule 05.03.2020