ReactJS App:是否可以命令特定div的渲染?

问题描述

我正在尝试创建一个ReactJS(使用react bootstrap)移动应用程序,该应用程序可以根据屏幕尺寸自行调整大小(扩展或收缩)。应用的一个部分的尺寸需要根据其他所有部分都呈现后在屏幕上剩余的空间来计算。

例如,考虑以下标记-

var calcWidth = (100 / tableSize).toString() + '%';
return( 
<Container>
    <Row id='1'>Header and other static stuff here</Row>
    <Row id='2'>
        //A db driven table with square shaped cells goes here. It has the below structure -
        <Container style={{width:'100%'}}>
            <Row><Col style={{width:calcWidth,paddingBottom:calcWidth}}></Col>...</Row>
            ...
        </Container>
    </Row>
    <Row id='3'>Footer and other static stuff here</Row>
</Container>
);

在上面的标记中,行ID 1和3包含静态内容,例如页眉,页脚,按钮,标题等。行ID 2包含一个表,该表可以包含“ n”个单元格,并且每个单元格都必须为正方形内容水平和垂直居中。

上面的代码可以根据容器的宽度正确计算每个单元的宽度(100%),并创建方形单元并完美地水平放置。但是由于高度与宽度相同,因此垂直高度会变大,并使页脚超出屏幕范围。我们要避免滚动条。解决方案似乎是根据表格可用的剩余高度来计算calcWidth,如下所示-

var remainingHeight = <total height of the container> - <height taken up by Row 1> - <height taken up by Row 3>
var width = <width of the screen>
var calcWidth = ((remainingHeight < width ? remainingHeight : width) / tableSize).toString() + '%';

我的问题是-

  1. 如何计算上面的剩余高度变量?如何让Row1和Row3在Row2之前渲染,然后计算剩余高度?
  2. 如何找到容器的总高度和宽度?
  3. 还有其他更好的方法吗?我只是一个新手,可能有一些CSS工具可以更有效地做到这一点?

解决方法

Here you can find an example on how to calculate the height of react components after rendering

enter image description here

export default function App() {
  const [height1,setHeigt1] = useState(0);
  const [height2,setHeight2] = useState(0);
  const [height3,setHeight3] = useState(0);
  const [remainingHeight,setRemainingHeight] = useState(0);

  useEffect(() => {
    const remainingHeight = 100 - height1 - height2 - height3;
    console.log(remainingHeight);
    setRemainingHeight(remainingHeight);
  },[setRemainingHeight,height1,height2,height3]);

  return (
    <div
      id="container"
      style={{
        height: "100px",backgroundColor: "firebrick",padding: "15px"
      }}
    >
      <ResizableComponent
        id="component-1"
        content={`Initial component 1 height = ${height1}`}
        onHeightUpdated={setHeigt1}
      />
      <ResizableComponent
        id="component-2"
        content={`Initial component 2 height = ${height2}`}
        onHeightUpdated={setHeight2}
      />
      <ResizableComponent
        id="component-3"
        content={`Initial component 3 height = ${height3}`}
        onHeightUpdated={setHeight3}
        remainingHeight={remainingHeight}
      />
    </div>
  );
}

export function ResizableComponent({
  id,content,onHeightUpdated,remainingHeight
}) {
  const [height,setHeight] = useState(0);
  const [isFirstRender,setIsFirstRender] = useState(true);

  useEffect(() => {
    const newHeight = document.getElementById(id).clientHeight;
    if (height !== newHeight && isFirstRender) {
      setHeight(newHeight);
      setIsFirstRender(false);
    }
  },[isFirstRender,id,height,remainingHeight]);

  useEffect(() => {
    onHeightUpdated(height);
  },[height,onHeightUpdated]);

  return (
    <div
      id={id}
      style={
        remainingHeight
          ? {
              backgroundColor: "pink",height: `calc(${height}px + ${remainingHeight}px)`
            }
          : { backgroundColor: "pink" }
      }
    >
      {content}
    </div>
  );
}