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!
source:https://uonfu.com/
Github User Rank List