javascriptreactjsreact-image

How to replace a React component with another one when its state is changed


I'm pretty new with React and this is what i'm trying to accomplish:

I want to show a large image that takes 3-4 seconds to load, so i want to show user a loader, which is achievable using ReactImage from https://www.npmjs.com/package/react-image

Then i want to add an option to zoom, but the zoom function should only be available after the image is loaded successfully, so i'm planning to use https://www.npmjs.com/package/react-image-magnify

However there's no events or possible way to make the 2 communicate their states with each other so that in my render() function i can choose to use either ReactImage or ReactImageMagnify.

Any help would be appreciated.

Here is some pseudocode, i have a react component called Preview, and it has a render() function that returns either ReactImage or ReactImageMagnify

export class Preview extends React.Component {
    ...
    render() {
        ...
        // if image is not yet loaded then return ReactImage
        return(
                <ReactImage
                    src={this.getPreviewUrl()}
                    className=""
                    style={{ zIndex: 1 }}
                    alt=""
                    loader={<LoadingImage />}
                />
        )

        //if not, return ReactImageMagnify
        return(
                <ReactImageMagnify {...{
                    smallImage: {
                        alt: 'Chef Works',
                        isFluidWidth: true,
                        src: 'smallimage.png'
                    },
                    bigImage: {
                        alt: 'Chef Works',
                        isFluidWidth: true,
                        src: 'bigimage.png'
                    }
                }}/>

        )
    }
}

Solution

  • I realized all i needed from the ReactImage was just the loading icon when image is not yet loaded, so i implemented the same behavior based on Travis James' answer and have a conditional display property for the ReactImageMagnify instead. Code is as follows:

    import React, {useState} from "react";
    import ReactImageMagnify from 'react-image-magnify';
    import { LoadingImage } from 'ui/component/loading-image';
    
    import styles from './style.css';
    
    export const PreviewWithZoom = ({imageLink, zoomImageLink}) => {
        const [loaded, setLoaded] = useState(false);
        const [loadedZoom, setLoadedZoom] = useState(false);
    
        return(<>
            {loaded ? null : <LoadingImage />}
            <img
                style={loaded && !loadedZoom ? {} : {display: 'none'}}
                src={imageLink}
                onLoad={() => setLoaded(true)}
                alt=''
            />
            <img
                style={{display: 'none'}}
                src={zoomImageLink}
                onLoad={() => setLoadedZoom(true)}
                alt=''
                />
    
            <div style={loaded && loadedZoom ? {} : {display: 'none'}}>
                <ReactImageMagnify {...{
                    className: styles.previewZoom,
                    smallImage: {
                        src: imageLink,
                        width: 670,
                        height: 670
                    },
                    largeImage: {
                        src: zoomImageLink,
                        width: 1500,
                        height: 1500,
                    }
                }}/>
            </div>
        </>);
    };