В настоящее время я визуализирую дочерний компонент при возникновении 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 Overflow, говорит мне создать объект img внутри метода componentDidMount(), чтобы браузер загрузил его. Я так и сделал, как вы можете видеть из приведенного выше кода. Но теперь, когда я пытаюсь передать его в качестве опоры моему внучатому компоненту внутри моего метода render, я не могу получить доступ к img, потому что он был определен внутри другого метода.
Как лучше всего обойти это? Мне просто нужно, чтобы изображение было загружено и отображалось вместе с сообщением об ошибке. В противном случае сообщение об ошибке будет отображаться перед изображением, если ваш браузер еще не кэшировал его. Спасибо за помощь.
Если RoundImage ожидает путь, почему бы просто не использовать: <RoundImage src = {Newman}/>?
Я только что отредактировал, чтобы добавить код RoundImage.js. Спасибо.
@ Diodeus-JamesMacFarlane Я пробовал это. Он работает, но не загружает мое изображение заранее. "Привет, Ньюман!" отображается перед изображением. А затем, как только браузер загрузит его, он загрузится ...
Если вы хотите предварительно загрузить его, вам нужно создать новый Image () выше в вашем приложении. К моменту загрузки компонента изображение все еще отсутствует. Вам не нужно ссылаться на это изображение, вы просто хотите, чтобы браузер загрузил его. Когда вы используете его в своем компоненте, он уже будет кэширован.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Немного другой подход, но если у вас есть источник изображения заранее, вы можете добавить источник изображения в основной файл html в качестве ссылки с опцией предварительной загрузки. Браузер предварительно загрузит изображение (с относительно низким приоритетом), и когда ваше приложение загрузит изображение, оно должно быть кэшировано в памяти браузера.
<head>
..
..
<link rel = "preload" href = "<your_image_source_here>" as = "image">
...
</head>
В этом подходе мы отделяем процесс предварительной загрузки от кода. Это более актуально, когда у вас есть источник изображения заранее (а не динамически) и когда вам не нужно кэшировать большое количество изображений (будет немного беспорядочно добавлять большой список ссылок в заголовок html, хотя возможный)
вы можете узнать больше о предварительной загрузке ссылок здесь: Предварительная загрузка содержимого с помощью rel = "preload"
Спасибо за вашу помощь. Однако мне действительно нужно, чтобы это было внутри компонента.
Я уже импортирую его в import Newman from '../../../../assets/newman-min.png'; Обмотка require какая разница?
Нет, на самом деле его эквивалент (:
Загрузка изображения происходит в браузере. Рендеринг в DOM также происходит в браузере.
Под предварительная загрузка вы имеете в виду, что хотите, чтобы компонент отображался только тогда, когда изображение готово?
Если да, вы можете сделать что-то вроде этого:
componentDidMount() {
const img = new Image();
img.onload = () => {
// when it finishes loading, update the component state
this.setState({ imageIsReady: true });
}
img.src = Newman; // by setting an src, you trigger browser download
}
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
}
}
Это то, что я искал. Просто изменил this.state({ imageIsReady: true }); вашего ответа на this.setState(...), и он работает так, как я задумал. Большое спасибо.
Ах да, спасибо за исправление. Я исправил опечатку в своем ответе.
img.src следует размещать после img.onload. В противном случае вы рискуете, что onload не запустится, если изображение будет кэшировано в браузере.
В моем случае я начинаю с начального атрибута src для своих изображений и хотел отложить их изменение после, изображение было загружено браузером, поэтому я написал следующий хук в Typescript:
import { useEffect, useState } from 'react';
export const useImageLoader = (initialSrc: string, currentSrc: string) => {
const [imageSrc, _setImageSrc] = useState(initialSrc);
useEffect(() => {
const img = new Image();
img.onload = () => {
_setImageSrc(currentSrc);
};
img.src = currentSrc;
}, [currentSrc]);
return [imageSrc];
};
Что такое «RoundImage»?