Achilles
Achilles

Reputation: 1129

ReactJS App: Is it possible to order the rendering of specific divs?

I'm trying to create a ReactJS (using react bootstrap) mobile app that can resize (expand or contract) itself based on the screensize. The dimensions of one part of the app need to be calculated based on how much space is left on the screen after all other parts have rendered.

For example, consider the below markup -

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>
);

In the above markup, Row id 1 and 3 contain static stuff like headers, footers, buttons, titles etc. The Row id 2 contains a table that can contain "n" number of cells and each cell needs to be square shaped with content horizontally and vertically centerd.

The above code correctly calculates the width of each cell from the width of the container (which is 100%) and creates square shaped cells and fits perfectly horizontally. But since the height is same as the width, it gets bigger vertically and drives the footer beyond the screen. We want to avoid scrollbars. The solution seems to be to calculate calcWidth based on the remaining height available to the table, something like the below -

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() + '%';

My questions are -

  1. How to calculate the remainingHeight variable above? How to let Row1 and Row3 render before Row2 and then calculate the remaining height?
  2. How to find the total height and width of the container?
  3. Any other better way of doing this? I'm just a newbie, probably there are some css tools to do it more efficiently?

Upvotes: 0

Views: 40

Answers (1)

Titulum
Titulum

Reputation: 11456

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, onHeightUpdated, remainingHeight]);

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

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

Upvotes: 1

Related Questions