2

I have a div element that I want to call a function from when a click event fires on it. The div contains an input field that I don't want to trigger the function, so I'm using useRef to target only the div element itself and not the contents. I'm creating the reference with the hook, giving the div a ref attribute pointing to that reference, and then passing it an onClick event that first checks if ref.current is equal to the event target. This method has worked for me in the past when building features such as modals, but for some reason this time the value of ref.current and the value of the event target are not evaluating as equal, and so the function never fires off. Here's the code:

const VideoEntryTile: React.FC = () => {
  const [isExpanded, setIsExpanded] = useState<boolean>(false);
  const containerRef = useRef<HTMLDivElement | null>(null)

  const handleExpand = (e: any):void => {
    console.log(containerRef === e.target) // This evaluates to false
    if (containerRef.current === e.target) {
      setIsExpanded(true)
    }
  }

  return (
    <div
      className={styles.VideoEntryTile__Container}
      onClick={handleExpand}
      ref={containerRef} {/* The reference is set here */}
    >
      <div className={styles.VideoEntryTile__Top}>
        <div className={styles.VideoEntryTile__LeftActions}>
          <div className={styles.VideoEntryTile__LeftActions__VideoNameInput}>
            <TextField
              disabled={false}
              inputSize="large"
              value="Video 1"
            />
          </div>
          <div className={styles.VideoEntryTile__LeftActions__GuestsContainer}>
            <p>Guests</p>
            <input />
          </div>
          <button type="button">-</button>
          <button type="button">+</button>
        </div>
        <div className={styles.VideoEntryTile__RightActions}>
          <p>20</p>
          <p>Credits</p>
        </div>
      </div>
      { isExpanded ?
        (
          <div className={styles.VideoEntryTile__Bottom}>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
          </div>
        )
        : null }
    </div>
  );
};

Any idea why this isn't working? This solution has worked for me in the past so I'm not sure why it isn't now.

E: This thread should not have been closed - the provided "answer" has nothing to do with my question.

3
  • This thread should not have been closed - the provided "answer" has nothing to do with my question. Commented Jan 12, 2022 at 17:58
  • Yeah I'm pretty sure this is not a duplicate of that question, this is about inequality of a ref value and event target, not the difference in general between currentTarget and target on an event. Commented Jan 12, 2022 at 18:33
  • Not sure why this doesn't work though. Could be that there isn't anywhere to actually click on the container. Try logging the event target and see if that helps. You might consider adding click handlers on the buttons that stop propagation so that clicking anywhere else in the container expands it, just not on the buttons (or any other elements you want to exclude). Commented Jan 12, 2022 at 18:49

1 Answer 1

1

I know this is an old topic and the question is very old, but maybe it will be useful to someone. 🤷‍♂️

Code:

const handleExpand = (e: any):void => {
  if (containerRef.current.contains(e.target)) {
    setIsExpanded(true)
  }
}

Problem:

In your case useRef is returning the current as an Object. By comparing the e.target which is a reference to the object onto which the event was dispatched and an Object the comparison will never be equal.

Solution:

Check if the reference to the object (returned by e.target) is contained inside the useRef.current node.

Sign up to request clarification or add additional context in comments.

1 Comment

If I understand correctly, this makes the handler react to clicks on the children nodes of said div, which is not the right behavior

Your Answer

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