Next.js Discord

Discord Forum

Reactivity not working

Answered
sup posted this in #help-forum
Open in Discord
Avatar
supOP
-# I'm trying to set opacity once the image has loaded - I'm extending the Nextjs Image component so that I can do this with all Images

'use client';

import ImageBase, { ImageProps } from 'next/image'; // Rename the import to avoid confusion
import { useState } from 'react';

const CustomImage: React.FC<ImageProps> = (props) => {
  const [isLoaded, setIsLoaded] = useState(false);

  return (
    <ImageBase
      {...props}
      className={`${props.className} transition-opacity duration-200 ${
        isLoaded ? 'opacity-100' : 'opacity-0'
      }`}
      onLoad={() => {
        console.log('Image loaded!');
        setIsLoaded(true);
      }}
    />
  );
};

// Export CustomImage as Image type
export default CustomImage as typeof ImageBase;
Answered by sup
Fixed below:

'use client';

import ImageBase, { ImageProps } from 'next/image'; // Rename the import to avoid confusion
import { useState } from 'react';

const CustomImage: React.FC<ImageProps> = (props) => {
  const [isLoaded, setIsLoaded] = useState(false);

  return (
    <ImageBase
      {...props}
      className={`${props.className} opacity-0 transition-opacity duration-700`}
      onLoad={(image) => {
        setIsLoaded(true);
        (image.currentTarget as HTMLImageElement).classList.remove('opacity-0');
        (image.currentTarget as HTMLImageElement).classList.add('opacity-100');
      }}
    />
  );
};

// Export CustomImage as Image type
export default CustomImage as typeof ImageBase;
View full answer

3 Replies

Avatar
supOP
So to be clear - the opacity does change if I change this line,

-# from:
className={`${props.className} transition-opacity duration-200 ${
  isLoaded ? 'opacity-100' : 'opacity-0'
}`}


-# to:
className={`transition-opacity duration-200 ${
  isLoaded ? 'opacity-100' : 'opacity-0'
}`}


But I don't see a fade-in, just a sudden change in state
Avatar
supOP
To add to the mix:

My usage here

<Image
  src={imageUrlBuilder(post.mainImage.asset._ref)}
  alt={post.mainImage.alt || 'Post image'}
  fill
  className='object-cover opacity-0 transition-opacity duration-700'
/>


Works! But only when I've defined half the stuff? As soon as I remove it, no fade :c
Avatar
supOP
Fixed below:

'use client';

import ImageBase, { ImageProps } from 'next/image'; // Rename the import to avoid confusion
import { useState } from 'react';

const CustomImage: React.FC<ImageProps> = (props) => {
  const [isLoaded, setIsLoaded] = useState(false);

  return (
    <ImageBase
      {...props}
      className={`${props.className} opacity-0 transition-opacity duration-700`}
      onLoad={(image) => {
        setIsLoaded(true);
        (image.currentTarget as HTMLImageElement).classList.remove('opacity-0');
        (image.currentTarget as HTMLImageElement).classList.add('opacity-100');
      }}
    />
  );
};

// Export CustomImage as Image type
export default CustomImage as typeof ImageBase;
Answer