这在 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.createElementelement.appendChild。相反,您应该使用 render() 函数来呈现文档。