title: How to get Position of Components using React Function Components
body: <p>I'm trying to do something like this:</p>
  <p><a href="https://i.stack.imgur.com/v1vkN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/v1vkN.png" alt="enter image description here" /></a></p>
  <p>When I click on a card on the left and then ctrl+click on a card on the right.. a line will be drawn.  Ctrl+click on the card on the right again and the line will be removed. I'm going to draw the line using an svg path but I have to get the positions of the cards in the <strong>Container Component</strong> to do so.</p>
  <p>I'm trying to do this with React Function Components using ref and I'm not quite getting it.  I understand that function components don't have an &quot;instance&quot; and therefore ref doesn't work quite like it does in classes.</p>
  <p>Please answer the following:</p>
  <ul>
  <li>Is it possible to do this with just function components?</li>
  <li>Which components require to be wrapped in React.forwardRef()?</li>
  <li>I read that I can just pass a function from the Container to the children in the ref attribute and the children can call that function when clicked.  Is that true and what would that look like?</li>
  <li>bonus: I've read through the <a href="https://reactjs.org/docs/refs-and-the-dom.html" rel="nofollow noreferrer">React Refs and the DOM</a> documentation several times and it just won't click for me. Can anyone explain it in my context?</li>
  </ul>
  <p>Any help is appreciated and thanks in advance!</p>
  <p><strong>EDIT</strong></p>
  <p>This is what I have so far:</p>
  <p><strong>ContainerComponent</strong></p>
  <pre><code>import React, { useState, useRef } from 'react';
  
  import { Container, Row, Col, Card, Button } from 'reactstrap';
  import SectionContainer from './SectionContainer';
  
  const ContainerComponent = (props) =&gt; 
  {
      const [keyCards, setKeyCards] = useState([
          { id: 1, name: 'key one', description: &quot;this is a key card for one&quot; },
          { id: 2, name: 'key two', description: &quot;this is a key card for two&quot; }
      ])
  
      const [valueCards, setValueCards] = useState([
          { id: 1, name: 'value one', description: &quot;this is a value card&quot; },
          { id: 2, name: 'value two', description: &quot;this is a value card&quot; },
          { id: 3, name: 'value three', description: &quot;this is a value card&quot; }
      ])
  
      const [connections, setConnections] = useState([
          // I need something like this for all connections that need a line
          {
              keyID: 1,
              keyPos: { x: 100, y: 200 },
              attachedValues: [
                  { valueID: 1, valPos: { x: 200, y: 200 } },
                  { valueID: 2, valPos: { x: 200, y: 300 } }
              ]
          }
      ])
  
      const cardRef = useRef()
  
      const getPositions = () =&gt;
      {
          console.log(cardRef.current)
          // if I can get positions and if they are selected
          // then I can set the state and generate svg paths
      }
  
      return (
          &lt;&gt;
              &lt;Row &gt;
                  &lt;Col className=&quot;display-section&quot; md='6'&gt;
                      &lt;SectionContainer
                          title=&quot;Rules for Life&quot;
                          items={keyCards}
                          cardRef={cardRef}
                          onClickHandler={getPositions}
                      /&gt;
                  &lt;/Col&gt;
  
                  &lt;Col className=&quot;display-section&quot; md='6'&gt;
                      &lt;SectionContainer
                          title=&quot;Entitlements for Days&quot;
                          items={valueCards}
                          cardRef={cardRef}
                          onClickHandler={getPositions}
                      /&gt;
                  &lt;/Col&gt;
              &lt;/Row&gt;
              {/* &lt;DrawLines connections={connections} /&gt; */}
          &lt;/&gt;
      )
  }
  
  export default ContainerComponent 
  </code></pre>
  <p><strong>SectionContainer</strong></p>
  <pre><code>import React from 'react';
  
  import { Row, Input, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';
  
  import CardContainer from './CardContainer'
  
  const SectionContainer = ({ title, items, cardRef, onClickHandler }) =&gt; 
  {
      return (
          &lt;&gt;
              &lt;h6&gt;{title}&lt;/h6&gt;
              &lt;Row &gt;
                  &lt;InputGroup&gt;
                      &lt;InputGroupAddon addonType=&quot;prepend&quot; &gt;
                          &lt;InputGroupText&gt;filter:&lt;/InputGroupText&gt;
                      &lt;/InputGroupAddon&gt;
                      &lt;Input /&gt;
                  &lt;/InputGroup&gt;
              &lt;/Row&gt;
              &lt;CardContainer
                  items={items}
                  cardRef={cardRef}
                  onClickHandler={onClickHandler}
              /&gt;
          &lt;/&gt;
      )
  }
  
  export default SectionContainer
  </code></pre>
  <p><strong>Card Container</strong></p>
  <pre><code>import React from 'react'
  import { Container, Row } from 'reactstrap'
  import CardComponent from './CardComponent'
  
  const CardContainer = ({ items, cardRef, onClickHandler }) =&gt; 
  {
      const getItems = (items) =&gt;
      {
          return items.map(item =&gt;
          {
              return &lt;Row key={item.id}&gt;
                  &lt;CardComponent
                      item={item}
                      cardRef={cardRef}
                      onClickHandler={onClickHandler}
                  /&gt;
              &lt;/Row&gt;
          })
      }
      return (
          &lt;Container fluid className=&quot;node-container&quot;&gt;
              {getItems(items)}
          &lt;/Container&gt;
      )
  }
  
  export default CardContainer
  </code></pre>
  <p><strong>Card Component</strong></p>
  <pre><code>import React, { useState } from 'react';
  
  import { Card, CardHeader, CardTitle, CardBody, CardText } from 'reactstrap';
  
  const CardComponent = React.forwardRef(({ item, cardRef, onClickHandler }, ref) =&gt; 
  {
      return (
          &lt;Card ref={cardRef} &gt;
              &lt;CardHeader onClick={onClickHandler} &gt;
                  &lt;CardTitle&gt;{item.name}&lt;/CardTitle&gt;
              &lt;/CardHeader&gt;
              &lt;CardBody&gt;
                  &lt;CardText&gt;{item.description}&lt;/CardText&gt;
              &lt;/CardBody&gt;
          &lt;/Card&gt;)
  })
  
  export default CardComponent
  </code></pre>
  <p>This displays the cards similar to the drawing above no problem.  I just can't get the ref thing to work.</p>
  <p>I'm getting the following error for CardComponent even tho I have wrapped it with React.ForwardRef():</p>
  <blockquote>
  <p>Warning: Function components cannot be given refs. Attempts to access
  this ref will fail. Did you mean to use React.forwardRef()?</p>
  <p>Check the render method of <code>ForwardRef</code>.
  in Card (at CardComponent.js:8)
  ...</p>
  </blockquote>
  <p><strong>Edit</strong></p>
  <p>I fixed the forwardRef() error by wrapping my Card in a div. Even tho the bootstrap Card renders as a div, you can't ref it.</p>
  <p>Only one position is passing up to the ContainerComponent tho.  Still working on that.</p>
  <p><strong>New CardComponent</strong></p>
  <pre><code>import React, { useState } from 'react';
  
  import { Card, CardHeader, CardTitle, CardBody, CardText } from 'reactstrap';
  
  const CardComponent = ({ item, cardRef, onClickHandler }) =&gt;
      (
          &lt;div ref={cardRef}&gt;
              &lt;Card &gt;
                  &lt;CardHeader onClick={onClickHandler} &gt;
                      &lt;CardTitle&gt;{item.name}&lt;/CardTitle&gt;
                  &lt;/CardHeader&gt;
                  &lt;CardBody&gt;
                      &lt;CardText&gt;{item.description}&lt;/CardText&gt;
                  &lt;/CardBody&gt;
              &lt;/Card&gt;
          &lt;/div&gt;
      )
  
  
  export default CardComponent
  </code></pre>