React报错Cannot set property of undefined:为何axios回调中this未定义?
问题原因及解决方案
这个报错的核心原因是普通函数的this绑定规则导致的:你在axios的then和catch里用了传统的function()定义回调,这类函数的this是在调用时动态绑定的。当axios内部调用这个回调函数时,它的this指向并不是你的App组件实例,而是undefined(严格模式下),所以自然会报错“Cannot set property 'allQuotes' of undefined”。
下面给你三种常见的解决方法,任选其一即可:
方法1:使用箭头函数(最推荐)
箭头函数不会绑定自己的this,它会继承外层作用域的this(也就是你的组件实例)。修改代码如下:
class App extends Component { constructor() { super(); this.allQuotes = []; } componentDidMount() { axios.get("http://getquote.herokuapp.com/get") .then((response) => { // 换成箭头函数 this.allQuotes = response.data; console.log(response.data); this.getNewQuote(); }) .catch((error) => { // 同样换成箭头函数 console.log("Error: ", error); }); } }
方法2:提前保存组件的this到变量里
在回调函数外部,把组件实例的this存到一个变量(比如self、that),然后在回调里用这个变量代替this:
class App extends Component { constructor() { super(); this.allQuotes = []; } componentDidMount() { const self = this; // 保存组件实例的this axios.get("http://getquote.herokuapp.com/get") .then(function (response) { self.allQuotes = response.data; // 用self代替this console.log(response.data); self.getNewQuote(); }) .catch(function (error) { console.log("Error: ", error); }); } }
方法3:用bind()绑定this
通过bind(this)手动把组件实例的this绑定到回调函数上:
class App extends Component { constructor() { super(); this.allQuotes = []; } componentDidMount() { axios.get("http://getquote.herokuapp.com/get") .then(function (response) { this.allQuotes = response.data; console.log(response.data); this.getNewQuote(); }.bind(this)) // 绑定组件的this到回调 .catch(function (error) { console.log("Error: ", error); }.bind(this)); } }
额外建议
另外,在React组件中,通常我们会把需要响应更新的数据放到组件的state里,而不是直接挂载到实例上。比如你可以这样修改:
constructor() { super(); this.state = { allQuotes: [] }; } // 在then回调里用setState更新 this.setState({ allQuotes: response.data });
这样当数据变化时,组件会自动重新渲染,更符合React的状态管理逻辑。
内容的提问来源于stack exchange,提问作者MickeyTheMouse
相关产品推荐
相关产品推荐

