这在 React 方法中未定义
this is undefined in React method
我正在尝试使用 React 和 Web Audio 制作一个简单的合成器 API,但在使用某些方法时遇到了问题。这是我的代码:
import * as React from "react"
class Synth extends React.Component {
constructor(props) {
super(props);
this.state = {value: 0.5};
this.handleChange = this.handleChange.bind(this);
this.setup = this.setup.bind(this);
this.createKey = this.createKey.bind(this);
this.componentDidMount = this.componentDidMount.bind(this);
this.audioContext = null;
this.oscList = [];
this.mainGainNode = null;
this.wavePicker = document.querySelector("select[name='waveform']");
this.volumeControl = document.querySelector("input[name='volume']");
this.noteFreq = null;
this.customWaveform = null;
this.sineTerms = null;
this.cosineTerms = null;
}
componentDidMount(){
this.setup();
}
handleChange(event) {
this.setState({
value: event.target.value
});
}
createNoteTable(){
let noteFreq = [];
for (let i=0; i< 9; i++) {
noteFreq[i] = [];
}
noteFreq[3]["C"] = 130.81;
noteFreq[3]["C#"] = 138.59;
noteFreq[3]["D"] = 146.83;
noteFreq[3]["D#"] = 155.56;
noteFreq[3]["E"] = 164.81;
noteFreq[3]["F"] = 174.61;
noteFreq[3]["F#"] = 185.00;
noteFreq[3]["G"] = 196.00;
noteFreq[3]["G#"] = 207.65;
//etc...
return noteFreq;
}
createKey(note, octave, freq){
console.log("createKey() is firing");
let keyElement = document.createElement("li");
switch (freq) {
case 130.81:
keyElement.className = "white c1"
break;
case 146.83:
keyElement.className = "black cs1"
break;
case 164.81:
keyElement.className = "white c1"
break;
case 174.61:
keyElement.className = "white d1"
break;
//etc...
default:
break;
}
keyElement.dataset["freq"] = freq;
keyElement.dataset["note"] = note;
keyElement.dataset["octave"] = octave;
keyElement.addEventListener("mousedown", this.notePressed, false);
keyElement.addEventListener("mouseup", this.noteReleased, false);
keyElement.addEventListener("mouseover", this.notePressed, false);
keyElement.addEventListener("mouseleave", this.noteReleased, false);
return keyElement;
}
setup(){
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.noteFreq = this.createNoteTable();
this.mainGainNode = this.audioContext.createGain();
this.mainGainNode.connect(this.audioContext.destination);
this.mainGainNode.gain.value = this.state.value;
this.noteFreq.forEach(function(keys, idx) {
let keyList = Object.entries(keys);
let octaveElem = document.createElement("div");
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.sineTerms = new Float32Array([0, 0, 1, 0, 1]);
this.cosineTerms = new Float32Array(this.sineTerms.length);
this.customWaveform = this.audioContext.createPeriodicWave(this.cosineTerms, this.sineTerms);
for (let i=0; i<9; i++) {
this.oscList[i] = {};
}
}
然后我有 notePressed() 和 noteReleased() 函数,但它们似乎工作正常。
问题是在调用 this.createKey() 时出现此错误:
类型错误:无法读取未定义的属性(读取 'createKey')
如您所见,我尝试绑定几乎所有我必须的方法,看看它是否有帮助,但没有。任何帮助将不胜感激。
您的错误可能是由于 forEach
循环中的 function
关键字造成的。在那里你失去了你的 this
范围。您可以使用 for of
或箭头函数修复它。
this.noteFreq.forEach((keys, idx) => {
...
keyList.forEach((key) => {
...
}
}
此外,您的代码看起来更像是普通的 ES6 class,而不是 React class。在 React 中,您不使用 document.createElement
和 element.appendChild
。相反,您应该使用 render()
函数来呈现文档。
我正在尝试使用 React 和 Web Audio 制作一个简单的合成器 API,但在使用某些方法时遇到了问题。这是我的代码:
import * as React from "react"
class Synth extends React.Component {
constructor(props) {
super(props);
this.state = {value: 0.5};
this.handleChange = this.handleChange.bind(this);
this.setup = this.setup.bind(this);
this.createKey = this.createKey.bind(this);
this.componentDidMount = this.componentDidMount.bind(this);
this.audioContext = null;
this.oscList = [];
this.mainGainNode = null;
this.wavePicker = document.querySelector("select[name='waveform']");
this.volumeControl = document.querySelector("input[name='volume']");
this.noteFreq = null;
this.customWaveform = null;
this.sineTerms = null;
this.cosineTerms = null;
}
componentDidMount(){
this.setup();
}
handleChange(event) {
this.setState({
value: event.target.value
});
}
createNoteTable(){
let noteFreq = [];
for (let i=0; i< 9; i++) {
noteFreq[i] = [];
}
noteFreq[3]["C"] = 130.81;
noteFreq[3]["C#"] = 138.59;
noteFreq[3]["D"] = 146.83;
noteFreq[3]["D#"] = 155.56;
noteFreq[3]["E"] = 164.81;
noteFreq[3]["F"] = 174.61;
noteFreq[3]["F#"] = 185.00;
noteFreq[3]["G"] = 196.00;
noteFreq[3]["G#"] = 207.65;
//etc...
return noteFreq;
}
createKey(note, octave, freq){
console.log("createKey() is firing");
let keyElement = document.createElement("li");
switch (freq) {
case 130.81:
keyElement.className = "white c1"
break;
case 146.83:
keyElement.className = "black cs1"
break;
case 164.81:
keyElement.className = "white c1"
break;
case 174.61:
keyElement.className = "white d1"
break;
//etc...
default:
break;
}
keyElement.dataset["freq"] = freq;
keyElement.dataset["note"] = note;
keyElement.dataset["octave"] = octave;
keyElement.addEventListener("mousedown", this.notePressed, false);
keyElement.addEventListener("mouseup", this.noteReleased, false);
keyElement.addEventListener("mouseover", this.notePressed, false);
keyElement.addEventListener("mouseleave", this.noteReleased, false);
return keyElement;
}
setup(){
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.noteFreq = this.createNoteTable();
this.mainGainNode = this.audioContext.createGain();
this.mainGainNode.connect(this.audioContext.destination);
this.mainGainNode.gain.value = this.state.value;
this.noteFreq.forEach(function(keys, idx) {
let keyList = Object.entries(keys);
let octaveElem = document.createElement("div");
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.sineTerms = new Float32Array([0, 0, 1, 0, 1]);
this.cosineTerms = new Float32Array(this.sineTerms.length);
this.customWaveform = this.audioContext.createPeriodicWave(this.cosineTerms, this.sineTerms);
for (let i=0; i<9; i++) {
this.oscList[i] = {};
}
}
然后我有 notePressed() 和 noteReleased() 函数,但它们似乎工作正常。
问题是在调用 this.createKey() 时出现此错误: 类型错误:无法读取未定义的属性(读取 'createKey')
如您所见,我尝试绑定几乎所有我必须的方法,看看它是否有帮助,但没有。任何帮助将不胜感激。
您的错误可能是由于 forEach
循环中的 function
关键字造成的。在那里你失去了你的 this
范围。您可以使用 for of
或箭头函数修复它。
this.noteFreq.forEach((keys, idx) => {
...
keyList.forEach((key) => {
...
}
}
此外,您的代码看起来更像是普通的 ES6 class,而不是 React class。在 React 中,您不使用 document.createElement
和 element.appendChild
。相反,您应该使用 render()
函数来呈现文档。