correct the implementation of useMount

This commit is contained in:
Pig Fang 2020-06-06 10:12:16 +08:00
parent a1ce50609f
commit c7b8cdab40
5 changed files with 126 additions and 114 deletions

View File

@ -1,16 +1,20 @@
import { useEffect, useMemo } from 'react' import { useEffect, useRef } from 'react'
export default function useMount(selector: string): HTMLElement { export default function useMount(selector: string): HTMLElement | null {
const container = useMemo(() => document.createElement('div'), []) const container = useRef<HTMLDivElement | null>(null)
useEffect(() => { useEffect(() => {
const mount = document.querySelector(selector)! const mount = document.querySelector(selector)!
mount.appendChild(container) const div = document.createElement('div')
container.current = div
mount.appendChild(div)
return () => { return () => {
mount.removeChild(container) mount.removeChild(div)
container.current = null
} }
}, []) }, [])
return container return container.current
} }

View File

@ -238,87 +238,88 @@ const Show: React.FC = () => {
return ( return (
<React.Fragment> <React.Fragment>
{createPortal( {container &&
<React.Suspense fallback={<ViewerSkeleton />}> createPortal(
<Previewer <React.Suspense fallback={<ViewerSkeleton />}>
{...{ <Previewer
[texture.type === TextureType.Cape {...{
? TextureType.Cape [texture.type === TextureType.Cape
: 'skin']: textureUrl, ? TextureType.Cape
}} : 'skin']: textureUrl,
isAlex={texture.type === TextureType.Alex} }}
initPositionZ={60} isAlex={texture.type === TextureType.Alex}
> initPositionZ={60}
{currentUid === 0 ? ( >
<button {currentUid === 0 ? (
className="btn btn-outline-secondary" <button
title={t('skinlib.show.anonymous')} className="btn btn-outline-secondary"
disabled title={t('skinlib.show.anonymous')}
> disabled
{t('skinlib.addToCloset')}
</button>
) : (
<div className="d-flex justify-content-between align-items-center">
<div>
{liked && (
<button
className="btn btn-outline-success mr-2"
onClick={handleOpenModalApply}
>
{t('skinlib.apply')}
</button>
)}
{liked ? (
<button
className="btn btn-outline-primary mr-2"
onClick={handleRemoveItemClick}
>
{t('skinlib.removeFromCloset')}
</button>
) : (
<button
className="btn btn-outline-primary mr-2"
onClick={handleAddItemClick}
>
{t('skinlib.addToCloset')}
</button>
)}
{texture.type !== TextureType.Cape && (
<button
className="btn btn-outline-info mr-2"
onClick={handleSetAsAvatar}
>
{t('user.setAsAvatar')}
</button>
)}
{canBeDownloaded && (
<button
className="btn btn-outline-info mr-2"
onClick={handleDownloadClick}
>
{t('skinlib.show.download')}
</button>
)}
<button
className="btn btn-outline-info mr-2"
onClick={handleReport}
>
{t('skinlib.report.title')}
</button>
</div>
<div
className={liked ? 'text-red' : 'text-gray'}
title={t('skinlib.show.likes')}
> >
<i className="fas fa-heart mr-1" /> {t('skinlib.addToCloset')}
<span>{texture.likes}</span> </button>
) : (
<div className="d-flex justify-content-between align-items-center">
<div>
{liked && (
<button
className="btn btn-outline-success mr-2"
onClick={handleOpenModalApply}
>
{t('skinlib.apply')}
</button>
)}
{liked ? (
<button
className="btn btn-outline-primary mr-2"
onClick={handleRemoveItemClick}
>
{t('skinlib.removeFromCloset')}
</button>
) : (
<button
className="btn btn-outline-primary mr-2"
onClick={handleAddItemClick}
>
{t('skinlib.addToCloset')}
</button>
)}
{texture.type !== TextureType.Cape && (
<button
className="btn btn-outline-info mr-2"
onClick={handleSetAsAvatar}
>
{t('user.setAsAvatar')}
</button>
)}
{canBeDownloaded && (
<button
className="btn btn-outline-info mr-2"
onClick={handleDownloadClick}
>
{t('skinlib.show.download')}
</button>
)}
<button
className="btn btn-outline-info mr-2"
onClick={handleReport}
>
{t('skinlib.report.title')}
</button>
</div>
<div
className={liked ? 'text-red' : 'text-gray'}
title={t('skinlib.show.likes')}
>
<i className="fas fa-heart mr-1" />
<span>{texture.likes}</span>
</div>
</div> </div>
</div> )}
)} </Previewer>
</Previewer> </React.Suspense>,
</React.Suspense>, container,
container, )}
)}
<div className="card card-primary"> <div className="card card-primary">
<div className="card-header"> <div className="card-header">
<h3 className="card-title">{t('skinlib.show.detail')}</h3> <h3 className="card-title">{t('skinlib.show.detail')}</h3>

View File

@ -233,16 +233,17 @@ const Upload: React.FC = () => {
)} )}
</div> </div>
</div> </div>
{ReactDOM.createPortal( {container &&
<React.Suspense fallback={<ViewerSkeleton />}> ReactDOM.createPortal(
<Previewer <React.Suspense fallback={<ViewerSkeleton />}>
skin={type !== TextureType.Cape ? texture : undefined} <Previewer
cape={type === TextureType.Cape ? texture : undefined} skin={type !== TextureType.Cape ? texture : undefined}
isAlex={type === TextureType.Alex} cape={type === TextureType.Cape ? texture : undefined}
/> isAlex={type === TextureType.Alex}
</React.Suspense>, />
container, </React.Suspense>,
)} container,
)}
</> </>
) )
} }

View File

@ -17,13 +17,16 @@ const Previewer: React.FC<Props> = (props) => {
const skin = props.skin ? `${blessing.base_url}/textures/${props.skin}` : '' const skin = props.skin ? `${blessing.base_url}/textures/${props.skin}` : ''
const cape = props.cape ? `${blessing.base_url}/textures/${props.cape}` : '' const cape = props.cape ? `${blessing.base_url}/textures/${props.cape}` : ''
return ReactDOM.createPortal( return (
<React.Suspense fallback={<ViewerSkeleton />}> container &&
<Viewer skin={skin} cape={cape} isAlex={props.isAlex} showIndicator> ReactDOM.createPortal(
{props.children} <React.Suspense fallback={<ViewerSkeleton />}>
</Viewer> <Viewer skin={skin} cape={cape} isAlex={props.isAlex} showIndicator>
</React.Suspense>, {props.children}
container, </Viewer>
</React.Suspense>,
container,
)
) )
} }

View File

@ -28,19 +28,22 @@ const Previewer: React.FC<Props> = (props) => {
const { skin, cape, isAlex } = props const { skin, cape, isAlex } = props
return ReactDOM.createPortal( return (
is3d ? ( container &&
<React.Suspense fallback={<ViewerSkeleton />}> ReactDOM.createPortal(
<Viewer3d skin={skin} cape={cape} isAlex={isAlex}> is3d ? (
<React.Suspense fallback={<ViewerSkeleton />}>
<Viewer3d skin={skin} cape={cape} isAlex={isAlex}>
{switcher}
</Viewer3d>
</React.Suspense>
) : (
<Viewer2d skin={skin} cape={cape}>
{switcher} {switcher}
</Viewer3d> </Viewer2d>
</React.Suspense> ),
) : ( container,
<Viewer2d skin={skin} cape={cape}> )
{switcher}
</Viewer2d>
),
container,
) )
} }