reactjs - declarar tipo con React.useImperativeHandle()
function App(){
const cntEl:any = React.useRef(null); // I don't know what type should be here.
React.useEffect(()=>{
if(cntEl.current){ cuntEl.current.start() }
}, []);
return <Countdown ref={cntEl} />
}
const Countdown = React.forwardRef((props,ref) => {
React.useImperativeHandle(ref, ()=>({
start() {
alert('Start');
}
});
return <div>Countdown</div>
});
Intento usar un método de un componente hijo en un componente padre usando ref y React.useImperativeHandle().
Funciona bien.
pero no estoy satisfecho debido a const cntEl:any.
Creo que hay muchas maneras de evitar usar el tipo any que no conozco.
Solo necesito un tipo que pueda ser reemplazado por el tipo any.
Editado
Puedo ver (property) React.MutableRefObject<null>.current: null cuando paso el cursor sobre cntEl.current
Respuesta #1
La respuesta aceptada está demasiado complicada, solo necesitas declarar un tipo CountdownHandle.
Para mí será así:
// Countdown.tsx
export type CountdownHandle = {
start: () => void;
};
type Props = {};
const Countdown = React.forwardRef<CountdownHandle, Props>((props, ref) => {
React.useImperativeHandle(ref, () => ({
// start() has type inferrence here
start() {
alert('Start');
},
}));
return <div>Countdown</div>;
});
// The component uses the Countdown component
import Countdown, { CountdownHandle } from "./Countdown.tsx";
function App() {
const countdownEl = React.useRef<CountdownHandle>(null);
React.useEffect(() => {
if (countdownEl.current) {
// start() has type inferrence here as well
countdownEl.current.start();
}
}, []);
return <Countdown ref={countdownEl} />;
}
Respuesta #2
Te recomiendo que uses definiciones de tipo de manera más explícita
Por ejemplo, con React DT, puedes definir un componente exótico ref con ForwardRefRenderFunction en lugar de FC.
type CountdownProps = {}
type CountdownHandle = {
start: () => void,
}
const Countdown: React.ForwardRefRenderFunction<CountdownHandle, CountdownProps> = (
props,
forwardedRef,
) => {
React.useImperativeHandle(forwardedRef, ()=>({
start() {
alert('Start');
}
});
return <div>Countdown</div>;
}
export default React.forwardRef(Countdown);
y luego usa la utilidad de React ElementRef, TypeScript puede inferir el tipo exacto de ref de tu componente
const App: React.FC = () => {
// this will be inferred as `CountdownHandle`
type CountdownHandle = React.ElementRef<typeof Countdown>;
const ref = React.useRef<CountdownHandle>(null); // assign null makes it compatible with elements.
return (
<Countdown ref={ref} />
);
};
