React类组件setState报错:Cannot read properties of undefined
解决React类组件中setState调用时的undefined错误(登录/注册页面切换场景)
在开发简易登录站点时,通过aktivSide state控制登录与注册页面切换,点击"Registrer Bruker"按钮时出现错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
尝试在constructor中添加this.aktivSide.bind(this);后页面无法正常显示,以下是具体问题分析与修复方案:
问题根源
- 组件定义位置错误:
RegistrerBruker和LoggInn函数定义在render方法内部,导致函数内部的this无法指向App组件实例,调用this.setState自然会报错。 - State存储方式不当:直接将组件实例(
<LoggInn />)存入state不符合React最佳实践,应该用状态标识(如字符串)来控制渲染逻辑。 - div的onLoad事件无效:HTML的div元素不支持
onLoad事件,页面初始化逻辑应该放在类组件的生命周期方法中。 - 错误的bind操作:
aktivSide是state中的属性,不是类的方法,bind操作完全无效,反而可能引发其他问题。
修复方案
- 重构组件结构:将页面组件移到App类外部,通过props传递状态切换回调,确保
this指向正确。 - 修改state存储逻辑:用字符串(如
"login"、"register")作为aktivSide的取值,通过条件渲染切换页面。 - 使用生命周期初始化页面:用
componentDidMount替代无效的div onLoad事件,设置默认显示页面。 - 规范状态切换方法:定义类方法控制状态切换,确保
this指向App组件实例。
完整修正代码
import planB from "./plan_b.json" import logo from './bilder/logo.png' import './App.css'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEyeSlash, faEye } from '@fortawesome/free-solid-svg-icons' import React from 'react'; // 将页面组件移到类外部,通过props接收切换回调 function RegistrerBruker({ onSwitchToLogin }) { return ( <> <h1>Registrer Bruker</h1> <input type="text" placeholder='brukernavn' className='input_text'></input> <div className='passord'> <input type="password" placeholder='passord' className='input_text'></input> <FontAwesomeIcon className='eye_icon' id='eye_icon1' /> </div> <p id='passordTekst'>tom</p> <div className='knapper'> <button onClick={onSwitchToLogin} className='knapper_login'><p>Logg Inn</p></button> <button className='knapper_login'><p>Registrer deg</p></button> </div> </> ) } function LoggInn({ onSwitchToRegister }) { return ( <> <h1>Logg inn</h1> <input type="text" placeholder='brukernavn' className='input_text'></input> <div className='passord'> <input type="password" placeholder='passord' className='input_text'></input> <FontAwesomeIcon className='eye_icon' id='eye_icon1' /> </div> <p id='passordTekst'>tom</p> <div className='knapper'> <button className='knapper_login'><p>Logg Inn</p></button> <button onClick={onSwitchToRegister} className='knapper_login'><p>Registrer deg</p></button> </div> </> ) } class App extends React.Component { constructor(props) { super(props); this.state = { aktivSide: "login" // 用字符串标识当前页面状态 }; // 绑定类方法的this指向 this.switchToLogin = this.switchToLogin.bind(this); this.switchToRegister = this.switchToRegister.bind(this); } componentDidMount() { // 组件挂载完成后初始化页面状态 this.setState({ aktivSide: "login" }); } // 切换到登录页的方法 switchToLogin() { this.setState({ aktivSide: "login" }); } // 切换到注册页的方法 switchToRegister() { this.setState({ aktivSide: "register" }); } render() { return ( <> <div className="App"> <title>SpeedType</title> <header className="App-header"> <div id="topp"> <img id="logoen" width={300} src={logo} alt="SpeedType Logo"></img> </div> <button onClick={() => console.log(this.state.aktivSide)}>查看当前状态</button> {/* 根据状态渲染对应页面组件 */} {this.state.aktivSide === "login" && <LoggInn onSwitchToRegister={this.switchToRegister} />} {this.state.aktivSide === "register" && <RegistrerBruker onSwitchToLogin={this.switchToLogin} />} </header> </div> </> ) } } export default App;
关键修改说明
- 页面组件独立于App类,通过props接收回调函数,彻底解决
this指向问题。 - 使用字符串标识页面状态,符合React状态管理的规范,便于调试和扩展。
- 用
componentDidMount完成初始化,替代无效的div onLoad事件。 - 定义类方法控制状态切换,通过bind确保
this指向正确(也可直接用箭头函数定义方法省去bind步骤)。 - 条件渲染逻辑清晰,便于维护后续的页面扩展。
内容的提问来源于stack exchange,提问作者mikkle
相关产品推荐
相关产品推荐

