1

First of all I'm aver that someone already asked this question (this) but I don't exactly know how to use the answer in my project.

My problem:

I have a div with an id of square. I want to get the width of this element, and this is my code:

import React, { useEffect, useState } from 'react';
import './login.css';
import * as firebase from 'firebase';

//pic imports
//...
/pic imports end

function Login() {
  const pics_slide_ref = React.createRef();

  const [width, setWidth] = 0;

  useEffect(() => {
    if (pics_slide_ref.current) {
      setWidth(pics_slide_ref.current.getBoundingClientRect().width);
      console.log(width);
    }
  }, [])



  var choosenProfile = 'pic_1';
  function profileChoosen(id) {
    document.getElementById(choosenProfile).classList.remove('choosen');
    choosenProfile = id;
    document.getElementById(choosenProfile).classList.add('choosen');
  }

  return (
    <div className="login">
      <div className="login-container">
        <input placeholder="Your Email..." />
        <input placeholder="Your Username..." />
        <input placeholder="Your password..." />
        <div className="loged-out">
          <button className="sign-in">Sign in</button>
          <button className="sign-up">Sign up</button>
        </div>
        <div className="loged-in">
          <button className="sign-out">Sign out</button>
        </div>


      </div>

      <div className="pic-container">
        <div className="pic-choos">
          <span>Choose a profile pic</span>
        </div>
        <div className="pics">
          <div className="pics-compact">
            <span>&#60;</span>
            <div ref={pics_slide_ref} id="pics-slide-space" className="pics-slide-space">
              <div id="pics-slide-1" className="pics-slide-1">
                <img src={pic_1} alt="#" id="pic_1" onClick={() => profileChoosen('pic_1')} />
                <img src={pic_2} alt="#" id="pic_2" onClick={() => profileChoosen('pic_2')} />
                <img src={pic_3} alt="#" id="pic_3" onClick={() => profileChoosen('pic_3')} />
                <img src={pic_4} alt="#" id="pic_4" onClick={() => profileChoosen('pic_4')} />
                <img src={pic_5} alt="#" id="pic_5" onClick={() => profileChoosen('pic_5')} />
                <img src={pic_6} alt="#" id="pic_6" onClick={() => profileChoosen('pic_6')} />
                <img src={pic_7} alt="#" id="pic_7" onClick={() => profileChoosen('pic_7')} />
                <img src={pic_8} alt="#" id="pic_8" onClick={() => profileChoosen('pic_8')} />
                <img src={pic_9} alt="#" id="pic_9" onClick={() => profileChoosen('pic_9')} />
                <img src={pic_10} alt="#" id="pic_10" onClick={() => profileChoosen('pic_10')} />

              </div>
            </div>
            <span>&#62;</span>
          </div>
        </div>
      </div>
    </div>
  );
}

export default Login;

Unfortunately it does not work. Is there a simple way of getting the width? If there isn't can someone explain me in details that how to do it?

6
  • can you provide more code Commented Aug 24, 2019 at 19:52
  • What part should I post? Commented Aug 24, 2019 at 19:54
  • Your react component that has the square. Commented Aug 24, 2019 at 19:54
  • Take a look at react refs and ref callbacks: reactjs.org/docs/refs-and-the-dom.html#callback-refs Commented Aug 24, 2019 at 19:57
  • 1
    You have const [width, setWidth] = 0. Use useState(0), not just 0. Commented Aug 24, 2019 at 20:35

2 Answers 2

4

You can use ref and getBoundingClientRect() to get width of any element.

Define a ref in your constructor:

this.myRef = React.createRef()

Then, attach it to your component.

<YourComponent ref={this.myref} />

Then, call getBoundingClientRect() like this:

myref.current.getBoundingClientRect().width
Sign up to request clarification or add additional context in comments.

6 Comments

I try it... :))
I get: TypeError: Cannot read property 'getBoundingClientRect' of null
Component should be mounted before you call it. From where are you invoking the function? Try calling from componentDidMount, for example. @BudaÖrs
@BudaÖrs Attach the ref to your component. See second step in my answer :)
I am glad I could help! @BudaÖrs
|
2

You actually need to assign the ref to the div. Use the ref in combination with useState() and useEffect(). We integrate useEffect() because it runs right after the first render of the component, thus ensuring that the div and hence ref is valid.

Then we get the width of the div and store it in state so you can use it in your mark-up.

import React, {useEffect, useState} from 'react';

function SquareHolder() {
    const [width, setWidth] = useState(0)
    const square_ref = React.createRef();

    useEffect(() => {
       if(square_ref.current){
          setWidth(square_ref.current.getBoundingClientRect().width)
       }
    }, [])


    return (
        <div className="square" ref={square_ref}>
            The width is: {width}
        </div>
    );
}

export default SquareHolder;

See working sandbox: https://codesandbox.io/s/agitated-sara-fp319

10 Comments

I tried it, and i got: TypeError: arr[Symbol.iterator] is not a function :((
@BudaÖrs there's nothing referencing arr[] in the code you posted. :(. You need to give us more context.
I didn't know I have an arr[] either :(
@BudaÖrs my bad, the problem was here. Just use this line const [width, setWidth] = useState(0); I was missing the useState() call in my original code.
Great :). I'm glad that was helpful to you. @BudaÖrs
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.