소품을 통해 제공되는 이미지가 로드되었을 때 감지하고 반응에서 상태를 변경하는 방법은 무엇입니까?
최종 아바타 이미지를 로드하는 동안 다른 이미지(짝퉁 아바타)를 로드하고 싶습니다.이 아이디어는 프로펠러 이미지가 로드된 시점을 감지하고 상태를 변경하는 것입니다.가능합니까?어떤 아이디어?감사해요!
class ImageUser extends React.Component {
constructor(props) {
super(props);
this.state = {userImageLoaded: false};
let imageSrc = "";
if (!this.props.userImage) {
imageSrc = this.props.noUserImage;
} else {
imageSrc = this.props.userImage;
}
this.loadingImage = <img className={styles.imageUser}
src={this.props.loadingImage} alt="2"/>;
this.userImage =
<img onLoad={this.setState({userImageLoaded: true})}
className={styles.imageUser} src={imageSrc}
alt="1"/>;
}
render() {
let image = "";
if (this.state.userImageLoaded) {
image = this.userImage;
} else {
image = this.loadingImage;
}
return (
<div>
{image}
</div>
);
}
}
export default ImageUser;
여기에는 여러 가지 방법이 있지만 가장 간단한 방법은 최종 이미지를 숨긴 상태로 표시한 다음 로드된 이미지를 볼 수 있도록 뒤집는 것입니다.
JSBin 데모
class Foo extends React.Component {
constructor(){
super();
this.state = {loaded: false};
}
render(){
return (
<div>
{this.state.loaded ? null :
<div
style={{
background: 'red',
height: '400px',
width: '400px',
}}
/>
}
<img
style={this.state.loaded ? {} : {display: 'none'}}
src={this.props.src}
onLoad={() => this.setState({loaded: true})}
/>
</div>
);
}
}
브리건드가 받아들인 대답과 같은 대답이지만 훅스는:
const Foo = ({ src }) => {
const [loaded, setLoaded] = useState(false);
return (
<div>
{loaded ? null : (
<div
style={{
background: 'red',
height: '400px',
width: '400px'
}}
/>
)}
<img
style={loaded ? {} : { display: 'none' }}
src={src}
onLoad={() => setLoaded(true)}
/>
</div>
);
};
요소에 대한 참조를 사용하지만 기능 구성 요소와 활자 스크립트가 있는 후크를 사용하는 것과 동일한 아이디어:
import React from 'react';
export const Thumbnail = () => {
const imgEl = React.useRef<HTMLImageElement>(null);
const [loaded, setLoaded] = React.useState(false);
const onImageLoaded = () => setLoaded(true);
React.useEffect(() => {
const imgElCurrent = imgEl.current;
if (imgElCurrent) {
imgElCurrent.addEventListener('load', onImageLoaded);
return () => imgElCurrent.removeEventListener('load', onImageLoaded);
}
}, [imgEl]);
return (
<>
<p style={!loaded ? { display: 'block' } : { display: 'none' }}>
Loading...
</p>
<img
ref={imgEl}
src="https://via.placeholder.com/60"
alt="a placeholder"
style={loaded ? { display: 'inline-block' } : { display: 'none' }}
/>
</>
);
};
이미지를 변경할 때 페이드인 전환을 추가하면 한 단계 더 나아갈 수 있습니다.의 코드입니다.CrossFadeImage
요. 보통 복사해서 쓰면 돼요.img
★★★★★★ 。
CrossFadeImage
.top
★★★★★★★★★★★★★★★★★」bottom
bottom
는 위에 쌓여서 애니메이션이 필요한 이미지(이 경우 전환 시 색이 바래지는 이전 이미지)를 표시하기 위해 사용됩니다.
에서는 " " " "top
현재 됩니다.bottom
입니다.
CrossFadeImage
는 을 검출할 때 동작을 합니다.props.src
사항
- 현재 실행 중인 애니메이션을 취소하려면 두 src를 모두 재설정합니다.
- ★★
top
로 변환하고 src를 src로 변환합니다bottom
프레임의 src에서 로 바랜다. - ★★
bottom
하게 전환의 시작을 .
import React from "react";
const usePrevious = <T extends any>(value: T) => {
const ref = React.useRef<T>();
React.useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
};
const useRequestAnimationFrame = (): [(cb: () => void) => void, Function] => {
const handles = React.useRef<number[]>([]);
const _raf = (cb: () => void) => {
handles.current.push(requestAnimationFrame(cb));
};
const _resetRaf = () => {
handles.current.forEach((id) => cancelAnimationFrame(id));
handles.current = [];
};
return [_raf, _resetRaf];
};
type ImageProps = {
src: string;
alt?: string;
transitionDuration?: number;
curve?: string;
};
const CrossFadeImage = (props: ImageProps) => {
const { src, alt, transitionDuration = 0.35, curve = "ease" } = props;
const oldSrc = usePrevious(src);
const [topSrc, setTopSrc] = React.useState<string>(src);
const [bottomSrc, setBottomSrc] = React.useState<string>("");
const [bottomOpacity, setBottomOpacity] = React.useState(0);
const [display, setDisplay] = React.useState(false);
const [raf, resetRaf] = useRequestAnimationFrame();
React.useEffect(() => {
if (src !== oldSrc) {
resetRaf();
setTopSrc("");
setBottomSrc("");
raf(() => {
setTopSrc(src);
setBottomSrc(oldSrc!);
setBottomOpacity(99);
raf(() => {
setBottomOpacity(0);
});
});
}
});
return (
<div
className="imgContainer"
style={{
position: "relative",
height: "100%"
}}
>
{topSrc && (
<img
style={{
position: "absolute",
opacity: display ? "100%" : 0,
transition: `opacity ${transitionDuration}s ${curve}`
}}
onLoad={() => setDisplay(true)}
src={topSrc}
alt={alt}
/>
)}
{bottomSrc && (
<img
style={{
position: "absolute",
opacity: bottomOpacity + "%",
transition: `opacity ${transitionDuration}s ${curve}`
}}
src={bottomSrc}
alt={alt}
/>
)}
</div>
);
};
export default CrossFadeImage;
사용.
<CrossFadeImage
src={image}
alt="phonee"
transitionDuration={0.35}
curve="ease-in-out"
/>
라이브 데모
https://stackoverflow.com/a/43115422/9536897이 도움이 됩니다.감사합니다.
당신을 강하게 하고 싶어요.배경 이미지를 위해서
constructor(){
super();
this.state = {loaded: false};
}
render(){
return (
<div>
{this.state.loaded ? null :
<div
style={{
background: 'red',
height: '400px',
width: '400px',
}}
/>
}
<img
style={{ display: 'none' }}
src={this.props.src}
onLoad={() => this.setState({loaded: true})}
/>
<div
style={ {
background: `url(${this.props.src})`
,display: this.state.loaded?'none':'block'
}}
/>
</div>
);
}
}```
이미지가 로드되는 시기를 감지하는 더 좋은 방법은 요소에 대한 참조를 만든 다음 참조에 이벤트 청취자를 추가하는 것입니다.요소에 이벤트 핸들러 코드를 추가하지 않고 다음과 같이 코드를 읽기 쉽게 할 수 있습니다.
class Foo extends React.Component {
constructor(){
super();
this.state = {loaded: false};
this.imageRef = React.createRef();
}
componentDidMount() {
this.imageRef.current.addEventListener('load', onImageLoad);
}
onImageLoad = () => {
this.setState({loaded: true})
}
render(){
return (
<div>
{this.state.loaded ? null :
<div
style={{
background: 'red',
height: '400px',
width: '400px',
}}
/>
}
<img
ref={this.imageRef}
style={{ display: 'none' }}
src={this.props.src}
/>
<div
style={{
background: `url(${this.props.src})`
,display: this.state.loaded?'none':'block'
}}
/>
</div>
);
}
}
다음은 React 로고에서 시작하여 업로드된 이미지로 대체하는 최소 React 예제입니다.
import React from 'react'
import logo from './logo.svg'
import './App.css'
export default function App() {
function loadImage(event) {
const file = event.target.files && event.target.files[0]
if (file) {
const img = document.querySelector("#image")
img.onload = () => window.URL.revokeObjectURL(img.src) // free memory
img.src = window.URL.createObjectURL(file)
}
}
return (
<div className="App">
<input type="file" id="inputfile" accept=".jpg" onChange={loadImage} />
<br/><br/>
<img src={logo} alt="upload" id="image" width={600} />
</div>
)
}
한 가지만 더하고 싶어요.수락된 답변은 괜찮지만, src가 소품에서 변경되면 로딩 부품이 표시되지 않습니다.소품 변경을 처리하려면 클래스 컴포넌트에 componentDidUpdate를 구현하고 기능 컴포넌트에 useEffect를 구현합니다.
class Foo extends React.Component {
constructor(){
super();
this.state = {loaded: false};
}
componentDidUpdate(prevProps){
if(prevProps.src!==this.props.src){
this.setState({loaded : false})
}
}
render(){
return (
<div>
{this.state.loaded ? null :
<div
style={{
background: 'red',
height: '400px',
width: '400px',
}}
/>
}
<img
style={this.state.loaded ? {} : {display: 'none'}}
src={this.props.src}
onLoad={() => this.setState({loaded: true})}
/>
</div>
);
}
}
또는 로드 이미지 또는 오류 이미지를 표시하는 경우 npm 패키지 "simple-react-image"를 사용할 수 있습니다.를 사용하여 설치하기만 하면 됩니다.
npm i 심플한 이미지
그 다음에 사용하시면 됩니다.또, 여기서 예를 확인하실 수 있습니다.
import React from 'react';
import { Image as Img } from 'simple-react-image';
class Foo extends React.Component {
render(){
return (
<div>
<Img
errorImage="https://www.freeiconspng.com/thumbs/error-icon/error-icon-32.png" //image in case of error
fallback="https://i.gifer.com/ZZ5H.gif"// image in case of loading
src={this.props.src}
onStateChange={(imageState)=>{
this.setState({imageState});//can be loading,loaded,error
}}
/>
</div>
);
}
}
순풍을 동반한 수락된 답변
const [isImageLoaded, setIsImageLoaded] = useState(false)
{!isImageLoaded && <img width={30} src='/images/spinner.svg' />}
<img
className={`mx-4 ${!isImageLoaded && 'hidden'}`}
width={30}
src="imageUrl"
onLoad={() => setIsImageLoaded(true)}
/>
솔루션:
import React, {FC,useState,useEffect} from "react"
interface ILoadingImg {
url:string,
classOk?:string,
classError?:string,
classLoading?:string
}
const LoadingImg: FC<ILoadingImg> = ({
url,
classOk,
classError,
classLoading
}) => {
const [isLoad,setIsLoad] = useState<boolean>(false)
const [error,setError] = useState<string|undefined>(undefined)
useEffect(() =>{
const image = new Image()
image.onerror = () =>{
setError(`error loading ${url}`)
setIsLoad( false)
};
image.onload = function() {
setIsLoad( true)
/*
//and you can get the image data
imgData = {
src: this.src,
width:this.width,
height:this.height
}
*/
}
image.src = url
return () => setIsLoad(false)
},[url])
if(!isLoad){
return <div className={classLoading}>Loading...</div>
}
if(error){
return <div className={classError}>{error}</div>
}
return <img src={url} className={classOk} />
}
export default LoadingImg
언급URL : https://stackoverflow.com/questions/43115246/how-to-detect-when-a-image-is-loaded-that-is-provided-via-props-and-change-sta
'programing' 카테고리의 다른 글
python에서 datetime 객체의 json 직렬화가 datetime 객체에 대해 즉시 작동하지 않는 이유는 무엇입니까? (0) | 2023.03.09 |
---|---|
jquery click이 Ajax 생성 콘텐츠에서 작동하지 않음 (0) | 2023.03.09 |
각도 8 및 Json 가져오기 (0) | 2023.03.04 |
Java 8 date/time type 'java.time.Instant'는 기본적으로 지원되지 않습니다. 문제: (0) | 2023.03.04 |
Uncaught TypeError: 정의되지 않은 SweetAlert & jquery의 속성 'then'을 읽을 수 없습니다. (0) | 2023.03.04 |