使用 React 和 Web Audio 进行状态管理

State Management with React and Web Audio

我正在尝试使用 Web Audio API 和 React 编写基于模块的音乐应用程序。

到目前为止,我一直在创建 Web 音频节点,例如过滤器、振荡器等,同时创建 React 组件:

class Filter extends React.Component {
    constructor(props) {
        super(props);
        const filter = props.context.createBiquadFilter();
        this.state = { filter };
    }
...

稍后,这意味着可以将过滤器作为组件状态的一部分进行更改:

    frequencyChange(event) {
        ...
        this.state.filter.frequency.setValueAtTime(range.value, context.currentTime);
    }

并在渲染方法中:

<input type="range" className="slider" min={20} max={20000}
                   onChange={event => this.frequencyChange(event)}/>

但是,当谈到将过滤器链接在一起时,我需要能够 disconnect() 我从该组件的父 class 创建的网络音频过滤器节点,并且 connect() 它到一个新的目的地。

假设父组件称为 EffectsBox,旨在呈现任意效果列表,如 Filter

下面是一些示例代码,希望能使我的问题更清楚:

class EffectsBox extends React.Component {
    ...

    addNewEffect(effect) {
        // disconnect() the previous effect and connect() it to a new one 
    }

    render() {
        // Maybe some kind of "map" here between effects and react components?
        return <div>{ this.state.effects }</div>
    }

N.B。 – 我读过 React 的 refs API,但它似乎不适合与任意数量的子 classes 一起使用 – 很高兴以其他方式展示!

React 不喜欢在不使用 setState 的情况下编辑组件状态中的值。我会避免将整个音频节点置于状态,甚至根本不置于组件中。

我曾经尝试在构造函数中将音频节点添加为 class 的一部分,这样我就可以像 this.filter 一样访问内容。然后我不得不 use refs everywhere 并将音频上下文传递给 everything 以访问连接节点和设置值所需的方法。它发出了我想要的声音,但我不喜欢我的文件如此紧密耦合和冗长。

我重构了一切。现在有一个文件使用管理所有音频节点的音频上下文。它公开了一些方法,我可以根据需要使用它来更新值。我还有一个字符串名称到节点的映射,所以我设置的值是这样的:setValue('filter', 'frequency', newValue)。有少数情况需要单独处理(即失真曲线),但总体上对我来说更容易阅读。这种抽象还意味着您的音频节点对组件层次结构的变化不敏感。

这是我推荐的。将你的音频节点从你的 React classes 中拉出来。管理管理节点的代码要简单得多。