2

I have got a dependency imageNo in useEffect() as I want the element to go up when it's being hidden, but scrollIntoView() does not work properly whenever imageNo changes, but it works when clicking a button.

Updated

import React, { useEffect, useRef, useState } from 'react';

const Product = ({ product }) => {
  const moveRef = useRef(product.galleryImages.edges.map(() => React.createRef()));
  const [imageNo, setImageNo] = useState(0);

  useEffect(() => {
    const position = moveRef.current[imageNo]?.current.getBoundingClientRect().y;

    console.log('imageNo', imageNo); // <<<<----- This is also called whenever scrolling excutes.

    if (position > 560) {
      moveRef.current[imageNo]?.current.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
    }
  }, [imageNo]);

  const test = () => {
    const position = moveRef.current[imageNo]?.current.getBoundingClientRect().y;

    if (position > 560) {
      moveRef.current[imageNo]?.current.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
    }
  };

  // This changes `imageNo`
  const handleScroll = () => {
    let id = 0;

    console.log('refs.current[id]?.current?.getBoundingClientRect().y', refs.current[id]?.current?.getBoundingClientRect().y);
    const temp = imgArr?.find((el, id) => refs.current[id]?.current?.getBoundingClientRect().y >= 78);

    if (!temp) id = 0;
    else id = temp.id;

    if (refs.current[id]?.current?.getBoundingClientRect().y >= 78) {
      setImageNo(id);
    }
  };


  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);


  return (
      <div className="flex flex-row layout-width ">
        {/* aside */}
        <div className="sticky flex self-start top-[76px] overflow-y-auto !min-w-[110px] max-h-[90vh]">
          <div className="">
            {product.galleryImages.edges.map((image, i) => {
              return (
                <div ref={moveRef.current[i]} key={image.node.id}>
                    <Image />
                </div>
              );
            })}
          </div>
        </div>
        <button onClick={test}>btn</button>
      </div>
  );
};

export default Product;

Any suggestion will be greatly appreciated.

1
  • Can you try without behavior: 'smooth'? I suspect that's what's causing the problem. This answer offers a workaround: stackoverflow.com/a/73297659/330565 Commented May 8, 2023 at 3:27

1 Answer 1

0

I couldn't see where the imageNo is coming from? If it is just a normal javascript variable then it wouldn't trigger re-render even after putting it inside the useEffect's dependencies array. If you want to make the re-render happen based on imageNo then make a useState variable for imageNo and change it using setter function that useState provides.

Helpful note - read about useState and useEffect hooks in React.

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

7 Comments

I have updated my question and added where imageNo is coming from. I put imageNo inside of uesState, but still not rerendered.
console.log imageNo inside a new useEffect and provide imageNo in its dependency array. And see if imageNo is actually being changed or not. I'm 100% sure that the setter of imageNo is not being called.
I checked console and imageNo is being changed..
console.log('imageNo', imageNo); // <<<<----- This is also called whenever scrolling executes. If the above line is called on scroll then this means your useEffect is re-executing. Then there could be nug in this if (position > 560) block. console.log inside this if block and check
In if (position > 560) block, the console also appears..
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.