React组件无法访问props问题:点击按钮触发TypeError报错求助
React组件中访问props报错的解决方案
错误原因
点击按钮触发action函数时,this.props.text抛出Cannot read properties of undefined (reading 'text')错误,核心问题是普通函数作为事件回调时,this指向发生了改变:这里的action是普通函数,当它作为按钮的点击事件监听器执行时,this指向的是触发事件的<button>元素,而非React组件实例,自然无法访问组件的props。
三种可行解决方案
方案1:使用箭头函数定义回调
箭头函数会继承外层作用域的this(也就是组件实例),直接解决this指向问题:
import React from "react"; class Canvas extends React.Component { componentDidMount() { const canvas = this.refs.canvas; const button = this.refs.button; const ctx = canvas.getContext("2d"); // 改用箭头函数 const action = () => { console.log("HI") ctx.font = "40px Consolas"; ctx.fillStyle = "#F5F5F5"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "#000000"; ctx.fillText(this.props.text, 10, 40); button.removeEventListener("click", action); } button.addEventListener("click", action); } render() { return ( <div> <canvas ref="canvas" width={300} height={300} /> <button ref="button" style={{ display: "block", margin: "auto", marginTop: "10px" }}>Show</button> </div> ); } } export default Canvas;
方案2:手动绑定this到回调函数
通过bind方法将组件实例的this绑定到action函数,注意要保存绑定后的函数引用,保证添加和移除监听器用的是同一个函数:
import React from "react"; class Canvas extends React.Component { componentDidMount() { const canvas = this.refs.canvas; const button = this.refs.button; const ctx = canvas.getContext("2d"); function action() { console.log("HI") ctx.font = "40px Consolas"; ctx.fillStyle = "#F5F5F5"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "#000000"; ctx.fillText(this.props.text, 10, 40); button.removeEventListener("click", boundAction); } // 绑定this并保存引用 const boundAction = action.bind(this); button.addEventListener("click", boundAction); } render() { return ( <div> <canvas ref="canvas" width={300} height={300} /> <button ref="button" style={{ display: "block", margin: "auto", marginTop: "10px" }}>Show</button> </div> ); } } export default Canvas;
方案3:提前保存组件实例的引用
在componentDidMount里用变量保存this(比如that),然后在action函数中通过这个变量访问props:
import React from "react"; class Canvas extends React.Component { componentDidMount() { const canvas = this.refs.canvas; const button = this.refs.button; const ctx = canvas.getContext("2d"); // 保存组件实例的引用 const that = this; function action() { console.log("HI") ctx.font = "40px Consolas"; ctx.fillStyle = "#F5F5F5"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "#000000"; // 使用that访问props ctx.fillText(that.props.text, 10, 40); button.removeEventListener("click", action); } button.addEventListener("click", action); } render() { return ( <div> <canvas ref="canvas" width={300} height={300} /> <button ref="button" style={{ display: "block", margin: "auto", marginTop: "10px" }}>Show</button> </div> ); } } export default Canvas;
内容的提问来源于stack exchange,提问作者user19934333
相关产品推荐
相关产品推荐

