能否从React组件构造函数外部获取组件实例的指针?
能否在JSX初始化组件的位置获取组件实例指针?
问题场景
现有React类组件代码:
import React, { Component } from 'react' class Frame extends Component { constructor(props) { super(props) console.log('constructor', this) // 需要获取的就是这个*this*(组件实例) } render() { return <p></p> } } export default Frame
通过以下方式初始化组件:
const view = <Frame /> console.log(view) // 想在此处获取组件实例
两处打印结果分别为:
{$$typeof: Symbol(react.element), key: null, ref: null, props: {…}, type: ƒ, …} constructor Frame {props: {…}, context: undefined, refs: {…}, updater: {…}}
问题:能否在const view = <Frame />的位置,获取到构造函数内的this(组件实例指针)?
答案
直接通过const view = <Frame />这种方式完全不可能拿到组件实例。
原因
<Frame />本质上是React.createElement(Frame)的语法糖,返回的是一个React元素对象(也就是你打印的第一个结果),它只是用来描述组件的类型、props、key、ref等信息的"虚拟DOM描述符",并不是实际的组件实例。
组件实例是React在渲染流程中才会创建的:当React把这个元素对象挂载到DOM上时,才会调用Frame的构造函数生成实例,这个过程发生在JSX创建之后的渲染阶段,所以在const view = <Frame />的位置,组件实例根本还没被创建。
可行的获取方式
如果需要拿到组件实例,得借助ref,根据使用场景不同有两种常见方式:
在父组件中获取
用createRef或者回调ref绑定到子组件上,在组件挂载完成后获取实例:import React, { Component, createRef } from 'react' import Frame from './Frame' class Parent extends Component { // 创建ref对象 frameRef = createRef() componentDidMount() { // 组件挂载后,ref.current就是Frame的实例 console.log('Frame组件实例:', this.frameRef.current) } render() { // 把ref传递给Frame组件 return <Frame ref={this.frameRef} /> } }在非组件环境(比如直接执行的脚本)中获取
通过ReactDOM.createRoot的ref赋值来拿到实例:import React from 'react' import ReactDOM from 'react-dom/client' import Frame from './Frame' const root = ReactDOM.createRoot(document.getElementById('root')) let frameInstance = null root.render( <Frame ref={(ref) => { // 组件挂载时会触发这个回调,ref就是实例 frameInstance = ref }} /> ) // 注意:同步打印可能还没完成挂载,可借助延时或渲染回调处理 setTimeout(() => { console.log('Frame组件实例:', frameInstance) }, 0)
内容的提问来源于stack exchange,提问作者scribe
相关产品推荐
相关产品推荐

