profile
viewpoint

Ask questionsKeep getting `TypeError: Cannot read property 'scrollTop' of null` in a custom hook...

I made a hook to get the scroll position of a component, like so:

function useScrollPosition() {

  function getScroll() {
    return {
      x: document.getElementById('ContentContainer').scrollTop,
      y: document.getElementById('ContentContainer').scrollLeft
    }
  }

  const [scrollPosition, setScrollPosition] = useState(getScroll)

  useEffect(() => {
    
    function handleScroll() {
      setScrollPosition(getScroll())
    }

    window.addEventListener('scroll', handleScroll)
    return () => window.removeEventListener('scroll', handleScroll)
  }, []) // Empty array ensures that effect is only run on mount and unmount

  return scrollPosition
}

...and implemented it in the same file, like so:

const ContentContainer = (props) => {

  const scroll = useScrollPosition();

  return (
    <Main id='ContentContainer'>
      <ScrollInfo>
        Vertical position: {scroll.x}px / Horizontal Position: {scroll.y}px
      </ScrollInfo>
      {props.children}
    </Main>
  )
}

export default ContentContainer

...and i keep getting the same error:

Screenshot 2019-07-03 00 38 46

If I disable the hook and the app runs properly, I can then find the scroll position in the console just fine.

Any thoughts as to why I might be getting null back for something that clearly isn't null when the app loads without this hook enabled?

facebook/react

Answer questions rchrdnsh

ok, I've tried to update the code using useRef, like so:

import React, { useState, useEffect, useRef } from 'react'
import styled from 'styled-components'

// styled components

const Main = styled.main`
  ...stylezzzz...
`

const ScrollInfo = styled.div`
  ...stylezzzz...
`

// hook

function useScrollPosition() {

  const elementRef = useRef(null);  

  function getScroll() {
    const data = elementRef.current ? 
      elementRef.current.getBoundingCLientRect() : 0;
    const { bottom, top, left, right } = data;
    return { bottom, top, left, right };
  }

  const [scrollPosition, setScrollPosition] = useState(getScroll)

  useEffect(() => {
    
    function handleScroll() {
      setScrollPosition(getScroll())
    }

    window.addEventListener('scroll', handleScroll)
    return () => window.removeEventListener('scroll', handleScroll)
  }, []) // Empty array ensures that effect is only run on mount and unmount

  return scrollPosition
}

// component

const ContentContainer = (props) => {

  const scroll = useScrollPosition();

  return (
    <Main ref={elementRef} id='ContentContainer'>
      <ScrollInfo>
        From Top: {scroll.top}px <br/>
        From Bottom: {scroll.bottom}px <br/>
        From Left: {scroll.left}px <br/>
        From right: {scroll.right}px <br/>
        Vertical Scroll: {scroll.y}px <br/>
        Horizontal Scroll: {scroll.x}px
      </ScrollInfo>
      {props.children}
    </Main>
  )
}

export default ContentContainer

and I'm currently getting the following error:

  122:16  error  'elementRef' is not defined  no-undef

✖ 1 problem (1 error, 0 warnings)

 @ ./src/components/Layout.js 17:0-45 91:140-144
 @ ./node_modules/gatsby-plugin-layout/wrap-page.js
 @ ./node_modules/gatsby-plugin-layout/gatsby-browser.js
 @ ./.cache/api-runner-browser-plugins.js
 @ ./.cache/api-runner-browser.js
 @ ./.cache/app.js
 @ multi ./node_modules/event-source-polyfill/src/eventsource.js
ℹ 「wdm」: Failed to compile.

but it appears that I am defining the ref at the beginning of the hook, no? Not sure how to adjust it to work properly.

useful!

Related questions

Disable react strict mode on third party libraries hot 3
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <table> hot 2
Warning: Unknown DOM property for. Did you mean htmlFor? hot 2
React@16.9 block `javascript:void(0);` hot 2
React custom hook "Should have a queue. This is likely a bug in React" error message. hot 1
TypeError: Object(...) is not a function hot 1
useEffect causes 'callback is not a function' exception hot 1
DevTools: Updating state or props in devtools does not trigger component update. hot 1
Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component hot 1
eslint-plugin-react-hooks v2.0.0 is not loaded correctly. hot 1
Old references retained by memoizedProps in fiber hot 1
Stale values for useState inside callback functions hot 1
ReactDomServer - renderToString Failing with Context Provider on IE11 hot 1
Route based code splitting, Loading chunk 0 failed after new deployment hot 1
map through connected component, get data of last saga call within all componenets hot 1
Github User Rank List