我多次遇到“对象可能为空”错误,通常我使用安全的“if 语句”以防它返回空值。
我有以下功能:
const ModalOverlay = (props: any[]) => {
const overlayEl = useRef(null);
useEffect(() => {
overlayEl.current.focus();
});
return <div {...props} ref={overlayEl} />;
}
但是 overlayEl.current
得到错误“对象未定义”。所以我试过:
if (!overlayEl) {
return null
} else {
useEffect(() => {
overlayEl.current.focus();
});
return <div {...props} ref={overlayEl} />;
}
这没有用。我也试过:
overlay && overlayEl.current.focus();
任何提示将不胜感激!谢谢
if ( overlay && overlay.current ) { overlayEl.current.focus(); }
之前检查 null
当您声明 const overlayEl = useRef(null);使其输出的类型为空,因为这是它可以提供这么多信息的最佳推断,为打字稿提供更多信息,它会按预期工作。
尝试....
const overlayEl = useRef<HTMLDivElement>(null);
或者,如果您不关心它的未定义何时执行此类操作,则可以使用一些语法糖。
const overlayEl = useRef(document.createElement("div"))
使用上述语法,所有常见的 DOM 方法只返回默认值,例如“0”,即 overlayEl.offsetWidth、getBoundingClientRect 等。
用法:
if(overlayEl.current) {
// will be type HTMLDivElement NOT HTMLDivElement | null
const whattype = overlayEl.current;
}
这种工作方式是打字稿静态分析足够聪明,可以找出 if
检查“防护”以防止 null,因此它将作为可能的类型从括号内的 null | HTMLDivElement
的联合中删除。
const overlayEl = useRef() as MutableRefObject<HTMLDivElement>;
它将 overlayEl
转换为已启动的 MutableRefObject,它是 useRef
的返回值:
function useRef<T = undefined>(): MutableRefObject<T | undefined>;
然而在这种情况下,编译器总是认为 overlayEl
有一个值。
[...] = useRef() as MutableRefObject<HTMLInputElement>
document.createElement("div")
将在第一次渲染时出错(关于文档的错误是 undefiend)
如@Shanon Jackson 所述,向 ref 添加一个类型:
const linkRef = useRef<HTMLLinkElement>(null);
然后,确保在使用 current
之前检查 null
值:
if (linkRef.current !== null) {
linkRef.current.focus();
}
这将满足 Typescript。而任何一个本身都不会。
使用 any
或强制转换来“欺骗”编译器会破坏使用 Typescript 的目的,不要那样做。
如果您想“通过/跳过”,那么这样做const overlayEl: any = useRef(null);
any
会危及拥有类型的目的 - 它使 overlayEl
任何类型都成为可能,因此所有类型信息都丢失了。 any
类型就像根本没有类型(vanilla js)。
any
。你还不如使用 javascript
我认为这比这里的其他答案更简洁:
const ModalOverlay = (props: any[]) => {
const overlayEl = useRef<HTMLDivElement>(null);
useEffect(() => {
overlayEl.current!.focus();
});
return <div {...props} ref={overlayEl} />;
}
您指定引用的类型,并声明您知道它不为空。
您还可以使用 ES2020 中引入的 optional chaining 代替“if”语句以获得更简洁的代码
const myRef = useRef<HTMLLinkElement>(null);
myRef.current?.focus();
您可以在 caniuse 查看其浏览器支持。
如果您真的知道在执行时您在这里没有错误,那么只需输入:
(overlayEl as any).current
如果没有,最好使用:
if (typeof overlayEl !== 'undefined' &&
typeof overlayEl.current !== 'undefined' &&
overlayEl.current === null) {
return;
}
// Or
try {
// you code here ...
// This is fine way to check by order -> parent.parent.FinalInstance
// Also try & catch will handle all bad situation about current error
overlay && overlayEl.current && overlayEl.current.focus();
} catch(e){
console.log("Real null >> ", e);
}
// Suggest if i am wrong in syntax somewhere ,this is fast answer ;)
typeof null
等于 object
而不是 "null"
并且绝对不是 null
。
有时我们useRef
不仅保存一个元素,还保存一个值,如数据。不知何故,当我检查 if(something.current) return something.current
时,即使 i
添加 && something.current!=null
所以我发现:
something.current!
告诉 typescript i
知道有一个值并绕过这个问题。
如果您不想给打字稿机会,请使用:
const iframe = useRef<HTMLIFrameElement | null>(null);
if (
typeof iframe !== "undefined" &&
typeof iframe.current !== "undefined" &&
iframe.current !== null
) {
iframe?.current?.contentWindow='';
);
}
取决于你喜欢什么,但一个好的语法和结构可能是创建一个接口:
interface divEL {
current: HTMLDivElement | null;
}
这将使您的声明保持清晰和简短,并且您可以将 divEl 接口重用于类似的 useRef 挂钩。
const overlayEl: divEL = useRef(null);
然后像这样添加焦点():
overlayEl.current!.focus();
current
之前还必须检查null
是很重要的。