Javascript 如何基于子组件大小更改父组件大小而不渲染子组件?

Javascript 如何基于子组件大小更改父组件大小而不渲染子组件?,javascript,reactjs,Javascript,Reactjs,我创建了一个React组件,它接受任何组件并将其呈现为弹出窗口。父组件接收要呈现(弹出)的组件。渲染组件在这里是使用react sizeme获取其大小并传递回父组件的子组件父组件必须采用子组件的尺寸,因此调整其高度和宽度。代码如下: 类弹出窗口扩展React.Component{ 建造师(道具:ipopuprops){ 超级(道具); 这个州={ childComponent:this.props.children, 风格:{ 高度:0,, 宽度:0 } } } //此函数在渲染子组

我创建了一个React组件,它接受任何组件并将其呈现为弹出窗口。父组件接收要呈现(弹出)的组件。渲染组件在这里是使用react sizeme获取其大小并传递回父组件的子组件父组件必须采用子组件的尺寸,因此调整其高度和宽度。代码如下:

类弹出窗口扩展React.Component{
建造师(道具:ipopuprops){
超级(道具);
这个州={
childComponent:this.props.children,
风格:{
高度:0,,
宽度:0
}
}     
}
//此函数在渲染子组件之前和之后运行两次
//由于此处的大小更改了两次,因此显示不正确(&S)
公共OnSize=(大小:任意)=>{
常数宽度=尺寸宽度+20;
常数高度=尺寸。高度+20;
这是我的国家({
样式:{高度,
宽度}
})
}
公共渲染(){
返回(
&时代;
)
}

}
实际上,这看起来像是更一般的DOM/JavaScript问题

考虑这种情况:

const span = document.createElement('span');
span.innerText = 'hello';
span.getBoundingClientRect() // -> { width: 0, height: 0, top: 0, … }
这是一个指示符,在元素进入DOM(在react中呈现)之前,您不知道元素的维度

在这种情况下,我向你提出的建议是:

  • 子组件应接受父组件的属性(函数)
  • 使用React“ref”功能查找子元素的实际尺寸
  • 调用“componentDidMount”中的函数(如果子级可以动态更改,则使用componentDidUpdate),将其传递给子组件维度 如果您无权访问子组件。您可以这样包装它:

    // Popup.tsx
    
    class Popup .... {
     ...
       render() {
         <Measurer>{this.props.children}</Measurer>
       }
    }
    
    //Popup.tsx
    类弹出窗口。。。。{
    ...
    render(){
    {this.props.children}
    }
    }
    

    并在其中实现了获取维度的逻辑。Measurer是Popup的直接子对象,其通信可由您控制

    shouldComponentupdate钩子就是为这种情况而存在的,我同时也在寻找这个问题。事实上,在渲染之前,我们无法获得组件的大小。我想我们不能使用shouldComponentUpdate,因为它根本不会被渲染。所以现在的问题是如何正确地将任何组件显示为弹出窗口。首先将其渲染到屏幕外(即视口外),获取测量值,然后在屏幕上渲染。@JaredSmith这个建议实际上奏效了。我和舍甫琴科打过answer@NikhilPatil这类似于游戏开发中的一个老把戏。因为游戏的帧预算很小(16毫秒),所以通常会将下一帧“绘制”到内存中的图像缓冲区中(快速且廉价)然后一次将整个内容替换为屏幕上的内容,而不是以增量方式(缓慢/昂贵)绘制场景中的每个对象。这种方法存在一个问题:父组件(Popup.tsx)从其主父组件(PopupBuilder.tsx)接收子组件。因此,要呈现的子组件不是在同一个类中导入的,因此我无法向子组件发送任何方法,我甚至尝试将“any”类型的子组件替换为“React.ComponentClass”和“React.component”。但它不起作用。这部分起作用了。谢谢在和我的popup.tsx中做了一些额外的更改。并将不透明度设置为0,以接受它作为答案
    // Popup.tsx
    
    class Popup .... {
     ...
       render() {
         <Measurer>{this.props.children}</Measurer>
       }
    }