现代React函数组件能否对外暴露可访问内部状态的方法?
问题原因
你当前的写法中,const inner = <Inner foo="bar" /> 拿到的是 React 元素对象,并不是子组件的实例,自然无法访问子组件内部定义的方法。函数组件本身没有类组件那样的实例,要实现对外暴露内部方法的需求,可以通过 forwardRef + useImperativeHandle 两个 React 内置能力实现。
完整修改代码
import { useState, useRef, forwardRef, useImperativeHandle } from 'react' // 定义Inner组件的入参类型 interface InnerProps { foo: string } // 定义Inner组件对外暴露的方法类型 interface InnerHandle { doTheThing: () => void } // 用forwardRef包裹组件,接收父组件传递的ref const Inner = forwardRef<InnerHandle, InnerProps>((props, ref) => { const [foo, setFoo] = useState<string>(props.foo + "baz") function doTheThing() { console.log(`doin' that ${foo} thing`) } // 把要对外暴露的方法挂载到ref上 useImperativeHandle(ref, () => ({ doTheThing })) return <div>{props.foo}</div> }) function Outer() { // 声明ref存储子组件暴露的实例 const innerRef = useRef<InnerHandle>(null) return ( <> <button onClick={() => innerRef.current?.doTheThing()}> Do That Thing </button> <Inner ref={innerRef} foo="bar" /> </> ) }
注意事项
- 这种方案属于命令式操作,不符合React声明式的设计理念,非必要场景不推荐使用。大部分需求可以通过提升公共状态到父组件、或者传入回调props的方式实现
- 访问
ref.current时建议添加可选链操作符,避免组件未挂载或已卸载时调用报错 - 如果你使用的是React 18及以上版本,
forwardRef包裹的组件支持泛型写法,不需要额外做类型断言
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

