能否在React类组件中使用useState Hook?如何转为函数组件?
React类组件中使用useState报错的原因及解决方法
问题背景
需要实现一个Message组件:点击锚点元素切换段落的显示状态——初始不显示,点击后显示,再次点击隐藏。
正确的类组件实现如下:
// React is loaded and is available as React and ReactDOM // imports should NOT be used class Message extends React.Component { constructor(props) { super(props); this.state = { visible: false }; } clickHandler = (event) => { event.preventDefault(); this.setState({ visible: !this.state.visible }); } render() { return (<React.Fragment> <a onClick={this.clickHandler} href="#">Want to buy a new car?</a> { this.state.visible && <p>Call +11 22 33 44 now!</p>} </React.Fragment>); } } document.body.innerHTML = "<div id='root'> </div>"; const rootElement = document.getElementById("root"); ReactDOM.render(<Message />, rootElement); console.log("Before click: " + rootElement.innerHTML); document.querySelector("a").click(); console.log("After click: " + rootElement.innerHTML);
尝试在类组件中使用useState Hook改写后报错,错误代码:
// React is loaded and is available as React and ReactDOM // imports should NOT be used class Message extends React.Component { const [show, setShow] = useState(false); const toggleVisibility = () => { setShow(!show); } render() { if(show) { return (<React.Fragment> <a onClick={toggleVisibility} href="#">Want to buy a new car?</a> <p>Call +11 22 33 44 now!</p> </React.Fragment>); } else { return (<React.Fragment> <a onClick={toggleVisibility} href="#">Want to buy a new car?</a> </React.Fragment>); } } } document.body.innerHTML = "<div id='root'> </div>"; const rootElement = document.getElementById("root"); ReactDOM.render(<Message />, rootElement); console.log("Before click: " + rootElement.innerHTML); document.querySelector("a").click(); console.log("After click: " + rootElement.innerHTML);
报错信息:
Run OK, but 3 out of 3 test cases failed. Line 5: SyntaxError: unknown: Unexpected token (5:8) 3 | class Message extends React.Component { 4 | > 5 | const [show, setShow] = useState(false); | ^ 6 | 7 | const toggleVisibility = () => { 8 | setShow(!show); Your score is 0% :(
报错原因
- Hooks使用规则限制:
useState是React Hooks的一种,Hooks的核心规则明确要求只能在函数组件或自定义Hooks的顶层作用域中调用,绝对不能在类组件中使用。类组件有独立的状态管理机制(this.state+this.setState()),和Hooks是两套完全不兼容的体系。 - 语法规范问题:JavaScript类的类体中,不能直接用
const/let声明变量,类体仅支持定义类属性、方法(包括箭头函数形式的类方法),这种直接写const的写法本身就违反了类的语法规范,这也是报错提示"Unexpected token"的直接原因。
正确的函数组件改写方案
将类组件转为函数组件,即可正常使用useState,同时要记得阻止a标签的默认跳转行为:
// React is loaded and is available as React and ReactDOM // imports should NOT be used function Message() { const [show, setShow] = React.useState(false); const toggleVisibility = (event) => { event.preventDefault(); // 阻止a标签默认跳转,避免状态重置 setShow(!show); }; return ( <React.Fragment> <a onClick={toggleVisibility} href="#">Want to buy a new car?</a> {show && <p>Call +11 22 33 44 now!</p>} </React.Fragment> ); } document.body.innerHTML = "<div id='root'> </div>"; const rootElement = document.getElementById("root"); ReactDOM.render(<Message />, rootElement); console.log("Before click: " + rootElement.innerHTML); document.querySelector("a").click(); console.log("After click: " + rootElement.innerHTML);
内容的提问来源于stack exchange,提问作者reactjs
相关产品推荐
相关产品推荐

