React组件Keen查询then回调调用setState报错:Cannot read property 'setState' of undefined
解决React中Keen查询回调里调用setState报错的问题
这个问题我之前也碰到过,核心是**this的指向出了问题**:在Promise的.then()回调函数里,普通函数的this并没有指向你的React组件实例,自然就找不到setState方法了。下面给你几种简单可行的解决办法:
方法1:使用箭头函数(最推荐)
箭头函数不会创建独立的this,它会直接继承外层作用域的this(也就是你的React组件实例)。修改.then()回调部分即可:
Keen.ready(function () { const element = document.getElementById('keen-table-chart'); const chart = new Keen.Dataviz() .el(element) .type('table') .height(400) .prepare(); client .query('extraction', { event_collection: 'Arrivy Datastore', timeframe: 'this_30_days', timezone: 18000, filters: filtersArray, property_names: propertyNames }) // 把普通函数改成箭头函数 .then(res => { this.setState({ queryResults: res }, () => { this.renderDataTable(res); }); }) .catch(err => { chart.message(err.message); }); });
方法2:提前保存组件的this引用
在回调函数外面,把组件的this存到一个变量里(比如self),之后在回调里用这个变量访问setState:
Keen.ready(function () { const element = document.getElementById('keen-table-chart'); const chart = new Keen.Dataviz() .el(element) .type('table') .height(400) .prepare(); // 提前保存组件实例的this const self = this; client .query('extraction', { event_collection: 'Arrivy Datastore', timeframe: 'this_30_days', timezone: 18000, filters: filtersArray, property_names: propertyNames }) .then(function(res) { // 用self代替this调用setState self.setState({ queryResults: res }, () => { self.renderDataTable(res); }); }) .catch(err => { chart.message(err.message); }); });
方法3:给回调函数绑定this
使用bind()方法,把回调函数的this强制绑定到组件实例上:
Keen.ready(function () { const element = document.getElementById('keen-table-chart'); const chart = new Keen.Dataviz() .el(element) .type('table') .height(400) .prepare(); client .query('extraction', { event_collection: 'Arrivy Datastore', timeframe: 'this_30_days', timezone: 18000, filters: filtersArray, property_names: propertyNames }) // 绑定this到组件实例 .then(function(res) { this.setState({ queryResults: res }, () => { this.renderDataTable(res); }); }.bind(this)) .catch(err => { chart.message(err.message); }); });
额外提醒
如果这段代码是写在React组件的生命周期方法(比如componentDidMount)里,建议把Keen.ready的回调也改成箭头函数,避免外层this指向异常:
componentDidMount() { Keen.ready(() => { // 改成箭头函数 const element = document.getElementById('keen-table-chart'); const chart = new Keen.Dataviz() .el(element) .type('table') .height(400) .prepare(); client .query('extraction', { event_collection: 'Arrivy Datastore', timeframe: 'this_30_days', timezone: 18000, filters: filtersArray, property_names: propertyNames }) .then(res => { this.setState({ queryResults: res }, () => { this.renderDataTable(res); }); }) .catch(err => { chart.message(err.message); }); }); }
这样就能顺利把查询结果存入组件state,渲染自定义数据表了。
内容的提问来源于stack exchange,提问作者Muhammad Arslan Aslam
相关产品推荐
相关产品推荐

