在 React 和 TypeScript 中使用类型化的 init 和 useRef 和 useEffect

问题描述

尝试在 React 应用中实现 ityped。下面显示代码应该可以在 JSX 中工作;然而,这个 React 应用程序是用 Typescript (TSX) 编写的,这就是它失败并出现类型错误的原因。

“Intro.tsx”组件:

import React,{ useEffect,useRef } from 'react';
import { init } from 'ityped';
import "./intro.scss";

export default function Intro() {

    const textRef = useRef(null);

    useEffect(() => {
        init(textRef.current,{ 
            showCursor: false,strings: ['Web developer','logo designer'] 
        })
    },[]);
    return (
        <div className="intro" id="intro">
            <div className="left">
                <div className="imgContainer">
                    <img src="assets/man.png" alt="" />
                </div>
            </div>
            <div className="right">
                <div className="wrapper">
                    <h2>Hi there,I'm</h2>
                    <h1>Andreas Petersen</h1>
                    <h3>A <span ref={textRef}></span> </h3>
                </div>
                <a href="#portfolio">
                    <img src="assets/down.png" alt="" />
                </a>
            </div>
        </div>
    )
}

错误如下:

Error Message

我的猜测是 const textRef = useRef(null); 需要以某种方式定义,以便来自 typed 的 init() 可以正确理解它。

解决方法

你需要做两件事。首先,就像你猜的那样,你需要指定这是什么类型的引用:

const textRef = useRef<HTMLSpanElement>(null);

其次,即使是那种类型,就类型而言,textRef.current 仍然可以为 null。所以你要么需要在你的使用效果中添加代码来检查是否为空:

useEffect(() => {
  if (!textRef.current) {
    return;
  }
  init(textRef.current,{ 
    showCursor: false,strings: ['Web developer','Logo designer'] 
  })
},[]);

或者,如果您确信在第一次渲染后它不可能为空(即,您无条件地将其传递给将使用它的组件),则可以使用非空断言 (!) 坚持打字稿你知道它不是空的:

useEffect(() => {
  init(textRef.current!,[]);

请注意,第二个选项意味着您告诉打字稿不要检查您的工作。如果您犯了一个错误并且它实际上可以为 null,则 typescript 无法告诉您这一点,并且您可能会在运行时出现意外行为。

,

是的,您需要为 useRef 添加类型,以便 Typescript 可以理解 ref 是针对 span 元素的。

试试这个:const textRef = useRef<HTMLSpanElement>(null);