Photo Album
code: github/
$ yarn 1225


usePhotoDetail
Custom Hooks 고장입니다. 평소와 같이 State, Option, MemoizedStyle, handler로 구성됩니다.
components/usePhotoDetail.tsconst usePhotoDetail = (props: Props) => {
const [state, update] = useState<State>(defaultState())
const options = useMemo(...)
const bgStyle = useMemo(...)
const photoStyle = useMemo(...)
const handleTouchMove = useCallback(...)
const handleOpen = useCallback(...)
const handleClose = useCallback(...)
return {
isOpen: state.isOpen,
isOpened: state.isOpened,
bgStyle,
photoStyle,
handleOpen,
handleClose
}
}
썸네일을 누르면 처리가 혼잡합니다. 누름 썸네일에서 줌 업 하도록(듯이), 시간차로 상태를 갱신해 CSS 애니메이션을 발화합니다.
components/usePhotoDetail.tsconst handleOpen = useCallback(
(e: MouseEvent<HTMLElement>) => {
// 押下された要素矩形を取得
const rect = ...
// アニメーション要素矩形初期値をセット
update(...)
// CSS アニメーション発火
setTimeout(() => {
update(_state => ({...}))
}, 16)
// 詳細 View 表示状態にセット
setTimeout(() => {
update(_state => ({...}))
}, options.transitionDuration)
},
[state.bgRect, state.photoRect, options]
)
Memoized Component
이미지 줌업의 거동에 3개의 컴퍼넌트를 이용하고 있습니다.
const usePhotoDetail = (props: Props) => {
const [state, update] = useState<State>(defaultState())
const options = useMemo(...)
const bgStyle = useMemo(...)
const photoStyle = useMemo(...)
const handleTouchMove = useCallback(...)
const handleOpen = useCallback(...)
const handleClose = useCallback(...)
return {
isOpen: state.isOpen,
isOpened: state.isOpened,
bgStyle,
photoStyle,
handleOpen,
handleClose
}
}
const handleOpen = useCallback(
(e: MouseEvent<HTMLElement>) => {
// 押下された要素矩形を取得
const rect = ...
// アニメーション要素矩形初期値をセット
update(...)
// CSS アニメーション発火
setTimeout(() => {
update(_state => ({...}))
}, 16)
// 詳細 View 表示状態にセット
setTimeout(() => {
update(_state => ({...}))
}, options.transitionDuration)
},
[state.bgRect, state.photoRect, options]
)
이미지 줌업의 거동에 3개의 컴퍼넌트를 이용하고 있습니다.
모두 이미지 경로는 동일합니다. iOS safari에서는 이미지 캐시가 남아 있어도 컴포넌트 마운트 시 다시 그려지고 깜박임이 발생합니다. 그 때문에,
useMemo 로 MemoizedComponent 를 보관 유지해, 재이용하는 것으로 이것을 회피할 수가 있습니다.components/index.tsx
const View = (props: Props) => {
const {
isOpen,
isOpened,
bgStyle,
photoStyle,
handleOpen,
handleClose
} = usePhotoDetail({ transitionDuration })
const photoComponent = useMemo(
() => <Photo imgPath={props.imgPath} />,
[props.imgPath]
)
return (
<div className={props.className}>
<div className="photo" onClick={handleOpen}>
{photoComponent}
</div>
{isOpen && (
<Detail
title={props.title}
body={props.body}
bgStyle={bgStyle}
photoStyle={photoStyle}
photoComponent={photoComponent}
isOpened={isOpened}
transitionDuration={transitionDuration}
handleClose={handleClose}
/>
)}
</div>
)
}
Photo 컴퍼넌트는 이렇게 얇습니다. 분할하는 것은 위의 이유와 같습니다.comonents/item/photo.tsx
const View = (props: Props) => (
<p className={props.className} />
)
Reference
이 문제에 관하여(Photo Album), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Takepepe/items/155d77a9c89a3fd29e26텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)