Skip to content

Commit

Permalink
Merge pull request #46 from roottool/feature/30/convert-LazyImage-to-FC
Browse files Browse the repository at this point in the history
Convert LazyImage to FC
  • Loading branch information
roottool committed Jan 16, 2022
2 parents 98a236c + 6c8d539 commit f98fc8f
Showing 1 changed file with 50 additions and 51 deletions.
101 changes: 50 additions & 51 deletions src/components/atoms/lazyImage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,71 @@
import CircularProgress from '@material-ui/core/CircularProgress'
import { withStyles, Theme, WithStyles, createStyles } from '@material-ui/core/styles'
import { Component } from 'react'
import { CircularProgress } from '@material-ui/core'
import { createStyles, withStyles, type Theme, type WithStyles } from '@material-ui/core/styles'
import BrokenImageIcon from '@material-ui/icons/BrokenImage'
import { useEffect, useRef, useState } from 'react'

const styleSettings = (theme: Theme) =>
interface Props {
src: string
title: string
}

const LoadingComponent = ({ classes: { progress } }: WithStyles<typeof loadingComponentStyle>) => (
<CircularProgress className={progress} />
)

const BrokenImageIconComponent = ({
classes: { root },
}: WithStyles<typeof brokenImageIconComponentStyle>) => <BrokenImageIcon className={root} />

const loadingComponentStyle = (theme: Theme) =>
createStyles({
progress: {
margin: theme.spacing() * 2,
},
})
const StyledLoadingComponent = withStyles(loadingComponentStyle)(LoadingComponent)

interface IProps extends WithStyles<typeof styleSettings> {
src: string
title: string
}

interface IState {
error: boolean
loaded: boolean
}
const brokenImageIconComponentStyle = (theme: Theme) =>
createStyles({
root: {
margin: theme.spacing() * 2,
},
})
const StyledBrokenImageIconComponent = withStyles(brokenImageIconComponentStyle)(
BrokenImageIconComponent
)

/**
* 参考URL
*
* https://stackoverflow.com/questions/53502271/react-img-tag-add-class-on-load
*/
class LazyImage extends Component<IProps, IState> {
constructor(props: IProps) {
super(props)
const useLazyImage = (src: Props['src']) => {
const imgRef = useRef(new Image())
const [isLoading, setIsLoading] = useState(true)
const [isError, setIsError] = useState(false)

this.state = {
error: false,
loaded: false,
useEffect(() => {
if (!imgRef.current.src) {
imgRef.current.src = src
imgRef.current.onload = () => setIsLoading(false)
imgRef.current.onerror = () => setIsError(true)
}
}
}, [imgRef, isLoading, setIsLoading, setIsError, src])

componentDidMount() {
const img = new Image()
img.onload = () => {
this.setState({
loaded: true,
})
}
img.onerror = () => {
this.setState({
error: true,
})
}
img.src = this.props.src
}
return { isError, isLoading }
}

render() {
const { classes } = this.props
const LazyImage = ({ src, title }: Props) => {
const { isError, isLoading } = useLazyImage(src)
if (isLoading) {
return <StyledLoadingComponent />
}

if (this.state.error) {
return (
<div>
<CircularProgress className={classes.progress} />
</div>
)
} else if (!this.state.loaded) {
return (
<div>
<CircularProgress className={classes.progress} />
</div>
)
}
return <img alt={this.props.title} src={this.props.src} title={this.props.title} />
if (isError) {
return <StyledBrokenImageIconComponent />
}

return <img alt={title} src={src} title={title} />
}

export default withStyles(styleSettings)(LazyImage)
export default LazyImage

0 comments on commit f98fc8f

Please sign in to comment.