Image onLoad event in isomorphic/universal react - register event after image is loaded

后端 未结 5 727

In isomorphic rendered page image can be downloaded before main script.js file. So image can be already loaded before react register onLoad

相关标签:
5条回答
  • 2020-12-23 15:04

    This is all a bit tidier with Hooks:

    
    const useImageLoaded = () => {
      const [loaded, setLoaded] = useState(false)
      const ref = useRef()
    
      const onLoad = () => {
        setLoaded(true)
      }
    
      useEffect(() => {
        if (ref.current && ref.current.complete) {
          onLoad()
        }
      })
    
      return [ref, loaded, onLoad]
    }
    
    const SomeComponent = ({ src }) => {
      const [ref, loaded, onLoad] = useImageLoaded()
    
      return (
        <div>
          <img ref={ref} onLoad={onLoad} src={src} alt="" />
          {loaded && <h1>Loaded!</h1>}
        </div>
      )
    }
    
    0 讨论(0)
  • 2020-12-23 15:12

    Another way is to use ref and cover those both scenarios:

    <img
      ref={(input) => {
        // onLoad replacement for SSR
        if (!input) { return; }
        const img = input;
    
        const updateFunc = () => {
          this.setState({ loaded: true });
        };
        img.onload = updateFunc;
        if (img.complete) {
          updateFunc();
        }
      }}
      src={imgSrc}
      alt={imgAlt}
    />
    
    0 讨论(0)
  • 2020-12-23 15:16

    You could check the complete property on the image before applying the onload event.

    if (!img.complete) {
        // add onload listener here
    }
    
    0 讨论(0)
  • 2020-12-23 15:16
    <img
        src={this.props.imageUrl}
        onLoad={this.handleImageLoaded.bind(this)}
        onError={this.handleImageErrored.bind(this)}
    />
    
    0 讨论(0)
  • 2020-12-23 15:23

    img.complete is true even when the src load fails.

    complete - Returns a Boolean that is true if the browser has finished fetching the image, whether successful or not. It also shows true, if the image has no src value.

    1. Use naturalWidth as determinant whether the img load was successfull or not
        state = {
            isLoading: true,
            hasError: false,
        }
    
        myRef = React.createRef();
    
        componentDidMount() {
            const img = this.myRef.current;
    
            if (img && img.complete) {
                if (img.naturalWidth === 0) {
                    this.handleOnError();
                } else {
                    this.handleImageLoaded();
                }
            }
        }
    
        handleImageLoaded = () => {
            if (this.state.isLoading) {
                this.setState({ isLoading: false });
            }
        }
    
        handleOnError = () => {
            this.setState({ hasError: true });
        }
    
        render() {
            return (
                <img
                    src={src}
                    alt={alt}
                    ref={this.myRef}
                    onError={this.handleOnError}
                    onLoad={this.handleOnLoad}
                />
            );
        }
    
    1. Another way is to add "check" image in componentDidMount a set eventHandler to it and let the check image be the one to handle eventListeners
    componentDidMount() {
       const testImg = new Image();
       testImg.onerror = this.handleOnError;
       testImg.onload = this.handleImageLoaded;
       testImg.src = this.props.src; // important to set eventlisteners before src
    }
    
    
    0 讨论(0)
提交回复
热议问题