React类组件点击事件中无法访问state与setState问题求助
React类组件计数器点击报错的解决方法
你遇到的Cannot read properties of undefined (reading 'clicks')和this.setState is not a function错误,本质都是类方法里的this指向不对。当通过原生addEventListener绑定clickHandler时,函数执行时的this会指向触发事件的DOM节点(也就是那个div),而不是你的App组件实例,自然找不到组件的state和setState方法。
下面给你三种靠谱的解决方法:
方法1:构造函数内手动绑定this
在组件构造函数里,给clickHandler绑定组件实例的this,这样不管怎么调用这个方法,this都会指向组件本身:
import React from "react"; class App extends React.Component { constructor(props) { super(props); this.state = { clicks: 0 }; this.myRef = React.createRef(); // 新增这行绑定this this.clickHandler = this.clickHandler.bind(this); } componentDidMount() { this.myRef.current.addEventListener("click", this.clickHandler); } componentWillUnmount() { this.myRef.current.removeEventListener("click", this.clickHandler); } clickHandler() { this.setState({ clicks: this.state.clicks + 1 }); } render() { return ( <div className="my-component" ref={this.myRef}> <h2>My Component ({this.state.clicks} clicks)</h2> </div> ); } }
方法2:用箭头函数定义类方法
箭头函数会自动继承外层作用域的this(也就是组件实例),直接把clickHandler改成箭头函数写法即可:
import React from "react"; class App extends React.Component { constructor(props) { super(props); this.state = { clicks: 0 }; this.myRef = React.createRef(); } componentDidMount() { this.myRef.current.addEventListener("click", this.clickHandler); } componentWillUnmount() { this.myRef.current.removeEventListener("click", this.clickHandler); } // 改成箭头函数 clickHandler = () => { this.setState({ clicks: this.state.clicks + 1 }); } render() { return ( <div className="my-component" ref={this.myRef}> <h2>My Component ({this.state.clicks} clicks)</h2> </div> ); } }
方法3:更符合React风格的写法(不用手动操作DOM)
其实React类组件里完全没必要手动用ref和原生事件监听,直接用JSX的onClick属性绑定事件更简单,还不用手动移除监听:
import React from "react"; class App extends React.Component { constructor(props) { super(props); this.state = { clicks: 0 }; // 依然需要绑定this(如果不用箭头函数方法的话) this.clickHandler = this.clickHandler.bind(this); } clickHandler() { this.setState({ clicks: this.state.clicks + 1 }); } render() { // 直接在div上绑定onClick return ( <div className="my-component" onClick={this.clickHandler}> <h2>My Component ({this.state.clicks} clicks)</h2> </div> ); } }
如果用箭头函数方法的话,连构造函数的绑定都可以省:
clickHandler = () => { this.setState({ clicks: this.state.clicks + 1 }); } // render里直接用 <div className="my-component" onClick={this.clickHandler}>...</div>
内容的提问来源于stack exchange,提问作者Synamon Kereys
相关产品推荐
相关产品推荐

