Rewrite GIFV component with React hooks (#24552)
parent
e5c0b16735
commit
cf3fa1e814
4 changed files with 70 additions and 78 deletions
@ -1,76 +0,0 @@ |
||||
import React from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
|
||||
export default class GIFV extends React.PureComponent { |
||||
|
||||
static propTypes = { |
||||
src: PropTypes.string.isRequired, |
||||
alt: PropTypes.string, |
||||
lang: PropTypes.string, |
||||
width: PropTypes.number, |
||||
height: PropTypes.number, |
||||
onClick: PropTypes.func, |
||||
}; |
||||
|
||||
state = { |
||||
loading: true, |
||||
}; |
||||
|
||||
handleLoadedData = () => { |
||||
this.setState({ loading: false }); |
||||
}; |
||||
|
||||
componentWillReceiveProps (nextProps) { |
||||
if (nextProps.src !== this.props.src) { |
||||
this.setState({ loading: true }); |
||||
} |
||||
} |
||||
|
||||
handleClick = e => { |
||||
const { onClick } = this.props; |
||||
|
||||
if (onClick) { |
||||
e.stopPropagation(); |
||||
onClick(); |
||||
} |
||||
}; |
||||
|
||||
render () { |
||||
const { src, width, height, alt, lang } = this.props; |
||||
const { loading } = this.state; |
||||
|
||||
return ( |
||||
<div className='gifv' style={{ position: 'relative' }}> |
||||
{loading && ( |
||||
<canvas |
||||
width={width} |
||||
height={height} |
||||
role='button' |
||||
tabIndex={0} |
||||
aria-label={alt} |
||||
title={alt} |
||||
lang={lang} |
||||
onClick={this.handleClick} |
||||
/> |
||||
)} |
||||
|
||||
<video |
||||
src={src} |
||||
role='button' |
||||
tabIndex={0} |
||||
aria-label={alt} |
||||
title={alt} |
||||
lang={lang} |
||||
muted |
||||
loop |
||||
autoPlay |
||||
playsInline |
||||
onClick={this.handleClick} |
||||
onLoadedData={this.handleLoadedData} |
||||
style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }} |
||||
/> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,68 @@ |
||||
import React, { useCallback, useState } from 'react'; |
||||
|
||||
type Props = { |
||||
src: string; |
||||
key: string; |
||||
alt?: string; |
||||
lang?: string; |
||||
width: number; |
||||
height: number; |
||||
onClick?: () => void; |
||||
} |
||||
|
||||
export const GIFV: React.FC<Props> = ({ |
||||
src, |
||||
alt, |
||||
lang, |
||||
width, |
||||
height, |
||||
onClick, |
||||
})=> { |
||||
const [loading, setLoading] = useState(true); |
||||
|
||||
const handleLoadedData: React.ReactEventHandler<HTMLVideoElement> = useCallback(() => { |
||||
setLoading(false); |
||||
}, [setLoading]); |
||||
|
||||
const handleClick: React.MouseEventHandler = useCallback((e) => { |
||||
if (onClick) { |
||||
e.stopPropagation(); |
||||
onClick(); |
||||
} |
||||
}, [onClick]); |
||||
|
||||
return ( |
||||
<div className='gifv' style={{ position: 'relative' }}> |
||||
{loading && ( |
||||
<canvas |
||||
width={width} |
||||
height={height} |
||||
role='button' |
||||
tabIndex={0} |
||||
aria-label={alt} |
||||
title={alt} |
||||
lang={lang} |
||||
onClick={handleClick} |
||||
/> |
||||
)} |
||||
|
||||
<video |
||||
src={src} |
||||
role='button' |
||||
tabIndex={0} |
||||
aria-label={alt} |
||||
title={alt} |
||||
lang={lang} |
||||
muted |
||||
loop |
||||
autoPlay |
||||
playsInline |
||||
onClick={handleClick} |
||||
onLoadedData={handleLoadedData} |
||||
style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }} |
||||
/> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default GIFV; |
Loading…
Reference in new issue