Search code examples
javascriptreactjsreact-hooksuse-ref

Cannot get the updated the state value useState and UseEffect


I want to get the latest value of the state and use it inline style, but it firstly returns 0 values, then rendering updated the state. However, I cannot assign the values into the style.

const ImageCard = ({ image: { alt_description, urls } }) => {
  const [spans, setSpans] = useState(0);
  const imageRef = useRef(null);

  useEffect(() => imageRef.current.addEventListener('load', () => {
    const height = imageRef.current.clientHeight;
    const spans = Math.ceil(height / 10);
    setSpans({ spans });
  }));

  return (
    <div style={{ gridRowEnd: `span ${spans}` }}>
      <img ref={imageRef} alt={alt_description} src={urls.regular} />
    </div>
  );
}

console output:

10 0
{spans: 15}
{spans: 33}
...

Solution

  • You would not need useEffect for this. You can use the onLoad event of the img tag as follows:

    const ImageCard = ({ image: { alt_description, urls } }) => {
      const [spans, setSpans] = useState(0);
    
      const imageLoaded = e => {
        const height = e.currentTarget.clientHeight;
        const spans = Math.ceil(height / 10);
        setSpans({ spans });
      };
      //Dont forget to remove this line
      console.log(spans);
      return (
        <div style={{ gridRowEnd: `span ${spans}` }}>
          <img onLoad={imageLoaded} alt={alt_description} src={urls.regular} />
        </div>
      );
    };
    

    Working code sandbox example