Next.js Discord

Discord Forum

UseRef return null instead of the element

Answered
English Spot posted this in #help-forum
Open in Discord
English SpotOP
So i tried to make a component here that needs to reference from the parent element
This is the component
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import { useEffect, useState } from 'react';

export default function CarouselNavigation({
  carousel,
}: {
  carousel: HTMLDivElement;
}) {
  let scroll = (dir: number) => {
    let style = window.getComputedStyle(carousel);
    carousel.scrollBy({
      left:
        dir *
        (carousel.clientWidth -
          parseInt(style.paddingLeft, 10) -
          parseInt(style.paddingRight, 10) +
          parseInt(style.columnGap, 10)),
      behavior: 'smooth',
    });
  };

  let [isPrevDisabled, setPrevDisabled] = useState(true);
  let [isNextDisabled, setNextDisabled] = useState(false);

  useEffect(() => {
    let update = () => {
      setPrevDisabled(carousel.scrollLeft <= 0);
      setNextDisabled(
        carousel.scrollLeft >= carousel.scrollWidth - carousel.clientWidth
      );
    };

    update();

    if ('onscrollend' in document) {
      carousel.addEventListener('scrollend', update);
      return () => carousel.removeEventListener('scrollend', update);
    } else {
      carousel.addEventListener('scroll', update);
      return () => carousel.removeEventListener('scroll', update);
    }
  }, [carousel]);

  return (
    <div className='flex justify-end gap-2'>
      <button
        className='...'
        aria-label='Previous Page'
        disabled={isPrevDisabled}
        onClick={() => scroll(-1)}
      >
        <ChevronLeftIcon className='h-5 w-5' />
      </button>
      <button
        className='...'
        aria-label='Next Page'
        disabled={isNextDisabled}
        onClick={() => scroll(1)}
      >
        <ChevronRightIcon className='h-5 w-5' />
      </button>
    </div>
  );
}
Answered by Anay-208
pass the ref directly to the child, and access it in the child using carousel.current
View full answer

21 Replies

English SpotOP
This is the parent
export default function Category() {
  const ref = useRef<HTMLDivElement>(null);
  return (
    <>
      <div className='mx-auto max-w-md px-8'>
        <div
          ref={ref}
          className='no-scrollbar edge-mask -mx-8 grid min-h-[350px] max-w-3xl snap-x snap-mandatory grid-cols-[repeat(4,100%)] gap-4 overflow-auto px-8 py-4'
        >
          <div className='snap-center snap-always rounded-2xl border bg-white p-6 shadow-md'>
            <h3 className='mb-2 text-xl font-semibold text-gray-800'>
              Card title 1
            </h3>
            <p className='text-gray-600'>Card description</p>
          </div>
          // Repeat 4 times
        </div>
      </div>
      <CarouselNavigation carousel={ref.current as HTMLDivElement} />
    </>
  );
}

But somehow my useRef keep returning null
@English Spot Click to see attachment
use carousel.current.scrollLeft
@Anay-208 use `carousel.current.scrollLeft`
English SpotOP
i used it in my parent component, will it do any different?
@English Spot i used it in my parent component, will it do any different?
Its not expected do. try to use carousel.current.<function | attribute>
English SpotOP
sorry, i dont really get it
what do you mean by that? :o
@English Spot sorry, i dont really get it what do you mean by that? :o
instead of carousel.scrollLeft. use carousel.current.scrollLeft
@English Spot i used it in my parent component, will it do any different?
oh wait, If you used, then just try to console.log it
English SpotOP
there is nothing
carouse null
react-dom.development.js:20665 Uncaught TypeError: Cannot read properties of null (reading 'scrollLeft')
let me review the code once more
The issue is, it looks like you
are trying to pass a ref before its assigned to a value
pass the ref directly to the child, and access it in the child using carousel.current
Answer
Please let me know if your issue is resolved
English SpotOP
:o
it works now
@English Spot it works now
Ok, can you mark the message above is a solution?
Thanks
English SpotOP
Thank you!
Looks like i dont really understand how useRef works yet :bceTired3Dead3: