React类组件开发合成器调用createKey方法报this为undefined错误
问题根因
报错和你提前做的方法bind没有关系,核心问题出在setup方法内的forEach回调函数上:你使用了普通匿名函数作为forEach的入参,普通函数的this指向会随执行上下文动态变化,两层forEach内部的this已经不再指向Synth组件实例,自然读取不到createKey方法。
解决方案
有两种可落地的修改方式,任选其一即可:
方案1:将普通函数替换为箭头函数
箭头函数会继承外层上下文的this指向,修改setup中的forEach部分代码:
// 外层forEach替换为箭头函数 this.noteFreq.forEach((keys, idx) => { let keyList = Object.entries(keys); let octaveElem = document.createElement("div"); // 内层forEach也替换为箭头函数 keyList.forEach((key) => { console.log("key[0] = " + key[0]); console.log("idx = " + idx); console.log("key[1] = " + key[1]); try { octaveElem.appendChild(this.createKey(key[0], idx, key[1])); } catch(error){ console.log("Cannot create key... " + error); } }); });
方案2:给forEach传入this绑定参数
Array.prototype.forEach支持传入第二个参数作为回调函数的this指向,如果你需要保留普通函数写法,可以按如下修改:
// 外层forEach第二个参数传入this this.noteFreq.forEach(function(keys, idx) { let keyList = Object.entries(keys); let octaveElem = document.createElement("div"); // 内层forEach第二个参数也传入this keyList.forEach(function(key){ console.log("key[0] = " + key[0]); console.log("idx = " + idx); console.log("key[1] = " + key[1]); try { octaveElem.appendChild(this.createKey(key[0], idx, key[1])); } catch(error){ console.log("Cannot create key... " + error); } }, this); }, this);
额外注意事项
你当前在constructor中直接用document.querySelector获取页面DOM元素的逻辑有问题:constructor执行时组件还未挂载到页面DOM树中,这两个选择器大概率会返回null,建议把这部分DOM查询逻辑移到componentDidMount生命周期方法中,或者使用React的ref特性获取DOM,更符合React的开发规范。
内容的提问来源于stack exchange,提问作者Antoine Lèvesque-Roy
相关产品推荐
相关产品推荐

