0

[QUESTION EDITED AS IT WAS NOT CLEAR ENOUGH]

I am trying to simply get the width & height of one of the rendered <div/> on Child.js. This is a great example, but on my case I do not have jus one <div/>, but an array of containers dynamically rendered.

Issue:

I have restricted the number of refs being sent up to App.js as you can see on Child.js: line 12 hopping that it would work, having a stable data being received so I could setState for just the ref of the first <div> being rendered at Child.js.

It actually works on an "apparent" first iteration, but then, event though I am getting childData from just index 0 of Child.js, somehow childData iterates again and it becomes null, with the following error: Cannot read property 'getBoundingClientRect' of null

Here is my code

import React from "react";
import Child from "./Child";
import "./styles.css";

export default class App extends React.Component {
  state = {
    childDims: {
      width: "",
      heigth: ""
    }
  };

  gettingDimsFromChildDataDiv = childData => {
    const { height, width } = childData.getBoundingClientRect();
    console.log(`height: ${height} & width: ${width}`);
    this.setState(
      ({ childDims, ...restTop }) => ({
        childDims: {
          width,
          height
        },
        ...restTop
      }),   //It actually sets state once... But for some reason it iterates 
            //another time and childData becomes null...
      () => console.log("setting state", this.state.childDims)
    );
  };

  render() {
    return (
      <div className="App">
        <Child liftContainerDimensions={this.gettingDimsFromChildDataDiv} />
      </div>
    );
  }
}

import React from "react";

export default class Child extends React.Component {
  state = {
    dummyArray: [1, 2, 3, 4]
  };
  render() {
    return (
      <div>
        {this.state.dummyArray.map((donkey, index) => {
          let ref = null;
          //I tried to restrict the number of instances sent up to App.js
          // Hopping that it would make it possible to safely setState there
          if (index === 0) {
            ref = el =>
              this.props.liftContainerDimensions((this.container = el));
          }
          return (
            <div
              key={donkey}
              style={{ border: "1px solid red", margin: "5px" }}
              ref={ref}
            >
              {donkey}
            </div>
          );
        })}
      </div>
    );
  }
}

Arp
  • 979
  • 2
  • 13
  • 30
  • You can create a ref and attach it to the child component, and then use `ref.current.getBoundingClientRect()` which will give you an object containing width and height properties of the child. – JMadelaine Mar 25 '20 at 05:50
  • could you please illustrate @JMadelaine? – Arp Mar 25 '20 at 06:00

1 Answers1

0

Here's my take. It feels odd but this accomplishes what you want.

https://codesandbox.io/s/get-a-react-components-size-heightwidth-before-render-for-array-of-containers-chsy6

It uses hooks so it may look a little odd to you.

blu
  • 372
  • 1
  • 10
  • I am going to reformulate the question. The solution presented had already been achieve d by me. The issue I am having is on the moment of setting state. Getting the dims is not the issue here – Arp Mar 25 '20 at 14:45
  • Why do you want it in state? You can pass down a ref. What you're trying to do can cause endless update loops. – blu Mar 25 '20 at 15:53