使用 useRef 在 Reactjs 中从父级调用子函数
Call Child Function from Parent in Reactjs using useRef
代码是使用 React 函数式组件编写的。
单击父项中的按钮后,应触发函数 showAlert。就是这个要求。
目前在父组件childRef.current中无法调用showAlert()函数。我收到打字稿错误
Property 'showAlert' does not exist on type 'ForwardRefExoticComponent<RefAttributes<unknown>>'
父功能组件代码
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
import Child from './Child';
export default function App() {
const childRef = useRef<typeof Child>(Child);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current.showAlert() }}
>
Call Function
</button>
</div>
)
}
子功能组件
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})
export default Child
试试这个方法
useImperativeHandle(
ref,
() => ({
showAlert: () => { // like this here
alert("Child Function Called")
console.log('hello world')
}
}),
)
你几乎说对了,但是 typeof Child
没有给你一个准确的类型,因为 Child
组件本身的类型不够严格。它被推断为 forwardRef<unknown, {}>
。我们需要指定转发 ref 的类型才能使其正常工作。
我们可以为我们想要的 ref 定义一个接口:
interface CanShowAlert {
showAlert(): void;
}
我们在 Child
的 forwardRef
函数上设置了两个泛型。 CanShowAlert
是 ref 类型,{}
是 props 类型:
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
我们在 useRef
:
上使用相同的泛型
const childRef = useRef<CanShowAlert>(null);
您的初始值 useRef<CanShowAlert>(Child)
出现错误,因为 ref 是针对组件的 实例 ,但您传入的是组件函数本身。相反,我们使用 null
作为初始值。
ref 的 current
属性 要么是一个组件实例,要么是 null
,所以我们在调用之前需要确保它不是 null
showAlert
函数。为此,我们可以使用可选的链接运算符 ?.
。
childRef.current?.showAlert()
完整代码:
import React, {forwardRef, useRef, useImperativeHandle} from "react";
interface CanShowAlert {
showAlert(): void;
}
export default function App() {
const childRef = useRef<CanShowAlert>(null);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current?.showAlert() }}
>
Call Function
</button>
</div>
)
}
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})
代码是使用 React 函数式组件编写的。
单击父项中的按钮后,应触发函数 showAlert。就是这个要求。
目前在父组件childRef.current中无法调用showAlert()函数。我收到打字稿错误
Property 'showAlert' does not exist on type 'ForwardRefExoticComponent<RefAttributes<unknown>>'
父功能组件代码
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
import Child from './Child';
export default function App() {
const childRef = useRef<typeof Child>(Child);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current.showAlert() }}
>
Call Function
</button>
</div>
)
}
子功能组件
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})
export default Child
试试这个方法
useImperativeHandle(
ref,
() => ({
showAlert: () => { // like this here
alert("Child Function Called")
console.log('hello world')
}
}),
)
你几乎说对了,但是 typeof Child
没有给你一个准确的类型,因为 Child
组件本身的类型不够严格。它被推断为 forwardRef<unknown, {}>
。我们需要指定转发 ref 的类型才能使其正常工作。
我们可以为我们想要的 ref 定义一个接口:
interface CanShowAlert {
showAlert(): void;
}
我们在 Child
的 forwardRef
函数上设置了两个泛型。 CanShowAlert
是 ref 类型,{}
是 props 类型:
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
我们在 useRef
:
const childRef = useRef<CanShowAlert>(null);
您的初始值 useRef<CanShowAlert>(Child)
出现错误,因为 ref 是针对组件的 实例 ,但您传入的是组件函数本身。相反,我们使用 null
作为初始值。
ref 的 current
属性 要么是一个组件实例,要么是 null
,所以我们在调用之前需要确保它不是 null
showAlert
函数。为此,我们可以使用可选的链接运算符 ?.
。
childRef.current?.showAlert()
完整代码:
import React, {forwardRef, useRef, useImperativeHandle} from "react";
interface CanShowAlert {
showAlert(): void;
}
export default function App() {
const childRef = useRef<CanShowAlert>(null);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current?.showAlert() }}
>
Call Function
</button>
</div>
)
}
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})