Home > other >  How do I get the offset coordinates of a container in react.js?
How do I get the offset coordinates of a container in react.js?

Time:01-05

I have a class component which renders a container. I would like to print the offset of that container within the container. The react code below should explain what I am trying to do:

  render() {
    return (
      <div onPointerDownCapture={this.started} onPointerLeave={this.ended} onPointerUpCapture={this.ended} onm ouseMove={this.handleMouseMove} className='gesture-view'>
        {this.state.x || this.state.y ? "The mouse is at x: "   (this.state.x)   ", y: "   (this.state.y) : "Move the mouse over this box"}
        {"This is the offset: "container.offsetX}
      </div>
    );
  }

Fundamentally I want to create a container which contains text describing the position of the container relative to the entire visible view. I set the position and width of the container inside of css.

Any ideas on how to do this?

CodePudding user response:

You can do that with a ref. The div element will be available as the current property on the ref in componentDidMount (for the first render) and componentDidUpdate (for subsequent ones).

You create the ref via createRef, usually in the constructor:

this.divRef = React.createRef();

then in the lifecycle methods described above, you can use this.divRef.current to get the position. You can either set the position in state (after first checking that the values have changed), which will cause a new render, or directly insert the text into the div via this.divRef.current.textContent = ... or similar.

Here's an example using textContent:

class Example extends React.Component {
    constructor(props) {
        super(props);
        this.divRef = React.createRef();
    }

    componentDidMount() {
        this.showContainerOffset();
    }

    componentDidUpdate() {
        this.showContainerOffset();
    }

    showContainerOffset() {
        const {current} = this.divRef;
        if (!current) {
            return;
        }
        // Or put them in state, which will cause a re-render if they change
        current.textContent =
            `The container is at ${current.offsetLeft}, ${current.offsetTop}`;
    }

    render() {
        return (
            <div className="container" ref={this.divRef} />
        );
    }
}

ReactDOM.render(<div>
    <Example />
    <Example />
</div>, document.getElementById("root"));
.container {
    border: 1px solid grey;
    padding: 4px;
    margin-bottom: 4px;
}
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

Here's an example using state:

class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            offsetLeft: NaN,
            offsetTop:  NaN,
        };
        this.divRef = React.createRef();
    }

    componentDidMount() {
        this.showContainerOffset();
    }

    componentDidUpdate() {
        this.showContainerOffset();
    }

    showContainerOffset() {
        const {current} = this.divRef;
        if (!current) {
            return;
        }
        const {offsetLeft, offsetTop} = current;
        this.setState(prev => {
            if (offsetLeft !== prev.offsetLeft ||
                offsetTop  !== prev.offsetTop) {
                return {offsetLeft, offsetTop};
            }
            return null;
        });
    }

    render() {
        const {offsetLeft, offsetTop} = this.state;
        return (
            <div className="container" ref={this.divRef}>
                {isNaN(offsetLeft) ? null : `The container is at ${offsetLeft}, ${offsetTop}`}
            </div>
        );
    }
}

ReactDOM.render(<div>
    <Example />
    <Example />
</div>, document.getElementById("root"));
.container {
    border: 1px solid grey;
    padding: 4px;
    margin-bottom: 4px;
}
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

  •  Tags:  
  • Related