reactjs - createPortal - TypeScript document.getElementById tür sorunu, JavaScript düzgün çalışırken?
ReactDOM.createPortal kullanmaya çalışıyorum ve VSCode'da ne 'ReactDOM' ne de 'document' vurgulanıyor ve 'document.getElementById('overlay-root')' üzerine gelince bu hatayı alıyorum:
Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element'.
Type 'null' is not assignable to type 'Element'.
İşte kod:
import styles from './CartModal.module.css';
import ReactDOM from 'react-dom';
import Card from '../UI/Card/Card';
interface CartModalProps {
onClose?: () => void
}
const DisplayCartModal: React.FC<CartModalProps> = (props) => {
return ReactDOM.createPortal(
<>
<CartModal />
</>,
document.getElementById('overlay-root')
)
}
export default DisplayCartModal;
Dosya uzantısını .js olarak değiştirmeyi denedim, bunun bir TypeScript hatası olup olmadığını görmek için ve gerçekten de değiştirdiğimde (ve TS'ye özgü sözdizimini kaldırdığımda) her şey vurgulandı ve mükemmel çalıştı. Null dönmedi, doğru HTML Elementini döndürdü. Yardım çok takdir edilir!
Cevap #1
Sorun şu ki, document.getElementById('overlay-root') null olabilir. Siz (sanırım) onun olmayacağını biliyorsunuz, ama Typescript bunu bilmiyor.
Bunu bir ünlem işareti ile, şöyle yaparak, null olmama durumunu belirtebilirsiniz:
ReactDOM.createPortal(
<>
<CartModal />
</>,
document.getElementById('overlay-root')!
)
Eğer iddianız yanlışsa, bir çalışma zamanı hatası alırsınız, bu çok kötü bir şeydir.
Cevap #2
Typescript'te, createPortal Element türünde bir konteyner alır:
export function createPortal(children: ReactNode, container: Element, key?: null | string): ReactPortal;
Bu arada, document.querySelector bir Element veya Null döndürür
querySelector<E extends Element = Element>(selectors: string): E | null;
Bu, her ikisi için de uyumsuzluk demektir; bunu düzeltmek için, querySelector'den dönen nesneyi dönüştürmeniz gerekecek.
document.querySelector('#overlay-root') as Element,
Ancak herhangi bir hatayı yakalamak için, onu kullanmadan önce null olup olmadığını kontrol etmelisiniz, böylece hiç cast yapmanız gerekmez:
const DisplayCartModal: React.FC<CartModalProps> = (props) => {
const overlayRootEl = document.querySelector('#overlay-root');
return overlayRootEl
? ReactDOM.createPortal(
<>
<CartModal />
</>,
overlayRootEl,
)
: null;
};
