Как предварительно загрузить изображение в компонент React JS?

1

В настоящее время я рендеринг дочернего компонента, когда происходит signInError. signInError хранится в родительском компоненте и, если он не <SignInError/> нулю, он визуализирует компонент <SignInError/>, как <SignInError/> в коде ниже:

ParentComponent.js

  // Some code...

  render() {
    return(
      <div>
        <SignInForm
          doSignIn={this.doSignIn}
          resetSignInError={this.resetSignInError}
          signInError={this.state.signInError}
        />
        {this.state.signInError && <SignInError/>}
      </div>
    );
  }

Пока все хорошо, вот дочерний компонент SignInError.js

import React from 'react';
import RoundImage from '../../../UI/Common/RoundImage';
import Newman from '../../../../assets/newman-min.png';

class SignInError extends React.Component {
  constructor(props){
    super(props);
  }

    componentDidMount(){
    const img = new Image();
    img.src = Newman;
  }

  render(){
    return(
      <div>
      <div>
        <RoundImage src={img.src}/> // <--- img is undefined here!!!
      </div>
      <div>
        Hello... Newman!
      </div>
    </div>
    );
  }
}

export default SignInError;

RoundImage.js

import React from 'react';

const RoundImage = (props) => {
  return (
    <div>
      <img src={props.src}/>
    </div>
  );
}

export default RoundImage;

Как предварительно загрузить изображения в React.js?

Ответ на этот вопрос (ссылка выше) здесь, в потоке Stack Over, подсказывает мне создать объект img внутри метода componentDidMount() чтобы заставить браузер загрузить его. И я так и сделал, как видно из приведенного выше кода. Но теперь, когда я пытаюсь передать его как опору моему компоненту grand-child внутри моего метода render, я не могу получить доступ к img, потому что он был определен внутри другого метода.

Какой лучший способ обойти это? Мне просто нужно, чтобы изображение загружалось и отображалось вместе с сообщением об ошибке. В противном случае сообщение об ошибке будет отображаться перед изображением, если ваш браузер еще не кэшировал его. Спасибо за помощь.

  • 0
    Что такое "RoundImage"?
  • 0
    Если RoundImage ожидает путь, почему бы просто не использовать: <RoundImage src={Newman}/> ?
Показать ещё 3 комментария
Теги:
preload

2 ответа

2
Лучший ответ

Загрузка изображения происходит в браузере. Рендеринг в DOM также происходит в браузере.

Под предварительной загрузкой вы подразумеваете, что хотите, чтобы компонент отображался только тогда, когда изображение готово?

Если это так, вы можете сделать что-то вроде этого:

componentDidMount() {
  const img = new Image();
  img.src = Newman; // by setting an src, you trigger browser download

  img.onload = () => {
    // when it finishes loading, update the component state
    this.setState({ imageIsReady: true });
  }
}

render() {
  const { imageIsReady } = this.state;

  if (!imageIsReady) {
    return <div>Loading image...</div>; // or just return null if you want nothing to be rendered.
  } else {
    return <img src={Newman} /> // along with your error message here
  }
}
  • 0
    Это то, что я искал. Просто изменил свой ответ this.state({ imageIsReady: true }); to this.setState(...) и он работает так, как я и предполагал. Большое спасибо.
  • 1
    Ах да, спасибо за исправление. Я исправил опечатку в своем ответе.
0

Немного другой подход, но если у вас есть источник изображения заранее, вы можете добавить источник изображения в основной html файл как ссылку с опцией предварительной загрузки. Браузер предварительно загрузит изображение (с относительно низким приоритетом), и в то время, когда ваше приложение загрузит изображение, оно должно быть кэшировано в памяти браузера.

<head>
..
..
<link rel="preload" href="<your_image_source_here>" as="image">
...
</head>

В этом подходе мы отделяем процесс предварительной загрузки от кода. Это более актуально, когда у вас есть источник изображения заранее (и не динамически), и когда вам не нужно кэшировать большое количество изображений (будет немного грязно, если добавить большой список ссылок в заголовке HTML, хотя возможный)

Вы можете узнать больше о предварительной загрузке ссылки здесь: Предварительная загрузка контента с rel= "preload"

  • 0
    Спасибо за вашу помощь. Мне действительно нужно, чтобы он обрабатывался внутри компонента.
  • 0
    Я уже импортирую его в import Newman from '../../../../assets/newman-min.png'; Рана require какой-либо разницы?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню