React类组件调用useRef报Invalid hook call错误如何解决
问题产生原因
useRef()属于React Hook API,Hook只能在函数组件或者自定义Hook的函数体内部调用,完全不支持在类组件中使用。- 你编写的
Test是继承自React.Component的类组件,直接在类属性定义位置调用useRef()违反了Hook的调用规则,因此触发非法Hook调用的报错。 - 原代码还存在几个附带小问题:冗余引入了
useState、useEffect两个类组件无法使用的Hook,label的htmlFor属性和对应input的id不匹配,样式导入路径多写了一层斜杠。
修复方案
可根据自己的技术选型二选一:
方案1:保留类组件写法
类组件不需要用Hook创建ref,直接使用类组件原生支持的React.createRef()创建ref即可,原有componentDidMount的聚焦逻辑不用改动,修正后代码如下:
import React, { Component } from "react"; import styles from '../../styles/Home.module.css' interface Props {} class Test extends Component<Props> { nameRef = React.createRef<HTMLInputElement>(null); componentDidMount() { this.nameRef.current!.focus(); } render() { return ( <main className={styles.main}> <form action="/account/sign-up" method="post"> <label htmlFor="name">Name:</label> <input type="text" id="name" name="name" required ref={this.nameRef} /> <label htmlFor="email">Email address:</label> <input type="text" id="email" name="email" required /> <button type="submit">Submit</button> </form> </main> ) } } export default Test
方案2:改用函数组件+Hook写法
如果你就是想使用useRef这类Hook能力,可以把类组件改写为函数组件,用空依赖的useEffect实现等价于componentDidMount的执行时机,修正后代码如下:
import React, { useRef, useEffect } from "react"; import styles from '../../styles/Home.module.css' interface Props {} const Test = (props: Props) => { const nameRef = useRef<HTMLInputElement>(null); useEffect(() => { nameRef.current!.focus(); }, []); return ( <main className={styles.main}> <form action="/account/sign-up" method="post"> <label htmlFor="name">Name:</label> <input type="text" id="name" name="name" required ref={nameRef} /> <label htmlFor="email">Email address:</label> <input type="text" id="email" name="email" required /> <button type="submit">Submit</button> </form> </main> ) } export default Test
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

