Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react: element.getBoundingClientRect is not a function

i've got a component and want to use the Office-UI-Fabric-react component "Callout" when the mouse is hovering over a "Persona"-element.
The "Callout" works if i reference the 'div' enclosing the "Persona"-element
(using ref={this.setPersonaRef} ),
but componentRef={this.setPersonaRef} in the "Persona"-element leads to

Exception in CalloutContent.componentDidMount(): TypeError: element.getBoundingClientRect is not a function

Here is the component:

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Persona,PersonaSize } from 'office-ui-fabric-react/lib/Persona';
import { Callout } from 'office-ui-fabric-react/lib/Callout';

import {IHoverPersonaProps} from './IHoverPersonaProps';
import {IHoverPersonaState} from './IHoverPersonaState';

export default class HoverPersona extends React.Component < IHoverPersonaProps,IHoverPersonaState > {
   private personaRef: any;

    constructor(props) {
        super(props);

        this.state = {
            hover: false
        };

        this.setPersonaRef = this.setPersonaRef.bind(this);
    }

    setPersonaRef(element) {
        this.personaRef = element; 
    }

    MouseEnter() {
        this.setState({hover:true})
    } 

    MouseLeave() {
        this.setState({hover:false})
    }

    public render() : React.ReactElement < IHoverPersonaProps > {
            return  <div onMouseEnter={this.MouseEnter.bind(this)} onMouseLeave={this.MouseLeave.bind(this)}   >
                      <Persona {...this.props} size={PersonaSize.extraSmall} primaryText={this.props.value} componentRef={this.setPersonaRef} />
                      { this.state.hover && 
                       <Callout
                        className="ms-CalloutExample-callout"
                        ariaLabelledBy={'callout-label-1'}
                        ariaDescribedBy={'callout-description-1'}
                        coverTarget={false} 
                        gapSpace={0} 
                        target={this.personaRef}
                        setInitialFocus={true}
                        >
                            <div className="ms-CalloutExample-header">
                                <p className="ms-CalloutExample-title" id={'callout-label-1'}>
                                Test
                                </p>
                            </div>
                            <div className="ms-CalloutExample-inner">
                            <Persona {...this.props} size={PersonaSize.large} primaryText={this.props.value}  /> 
                            </div>
                       </Callout>

                     }
                    </div>;     
    }
}

How can i resolve the exception?

like image 628
user4531 Avatar asked Aug 22 '18 08:08

user4531


People also ask

Can I use getBoundingClientRect in react?

You can use Element. getClientRects() and Element. getBoundingClientRect() to get the size and position of an element. In React, you'll first need to get a reference to that element.

What is getBoundingClientRect()?

getBoundingClientRect() method returns a DOMRect object providing information about the size of an element and its position relative to the viewport.


2 Answers

Because to use getBoundingClientRect or other similar methods you need to point current property of ref.

From documentation:

useRef (or simple class ref) returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

Example:

function App() {
  const inputRef = useRef();
  const scrollHandler = _ => {
    console.log(inputRef.current.getBoundingClientRect());
  };
  useEffect(() => {
    window.addEventListener("scroll", scrollHandler, true);
    return () => {
      window.removeEventListener("scroll", scrollHandler, true);
    };
  }, []);
  return (
    <div ref={inputRef} className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Working Codesandbox (to show results scroll instead of codesandbox console use browser console)

like image 143
Randall Avatar answered Sep 29 '22 10:09

Randall


If you're defining the ref on the component level

like this:

<SomeComponent ref={yourRef} />

you'll get getBoundingClientRect() from the node property that comes from the first element rendered on the component

yourRef.current.node.getBoundingClientRect()
like image 29
JoaoVitorOBrabo Avatar answered Sep 29 '22 10:09

JoaoVitorOBrabo