Управление состоянием с помощью React и Web Audio - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь написать модульное музыкальное приложение с использованием Web Audio API и React.

До этого момента я создавал узлы веб-аудио, такие как фильтры, осцилляторы и т. Д. При создании компонентов 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() узел фильтра Web Audio, который я создал из родительского класса этого компонента, и connect() его нового назначения.

Допустим, родительский компонент называется EffectsBox и предназначенотобразить произвольный список эффектов, таких как Filter.

  • Как он должен отображать все эти компоненты, а также позволять им предоставлять некоторые общие API для объединения аудио вместе?

  • Где долженсостояние - т.е. веб-аудио компоненты - для этих эффектов будут сохранены?

Вот пример кода, который, надеюсь, прояснит мой вопрос:

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>
    }

Примечание: я читал об API React refs, но это не таккажется подходящим для использования с произвольным числом дочерних классов - очень рад, если его показывают иначе!

1 Ответ

0 голосов
/ 11 декабря 2018

React не нравится, когда вы редактируете значения в состоянии компонента без использования setState.Я бы не стал переводить весь аудио узел в состояние или даже в компонент.

В какой-то момент я пытался добавить аудио узел как часть класса в конструктор, чтобы я мог получить доступ к вещам как this.filter.Затем я должен был использовать ссылки везде и передавать аудиоконтент на все , чтобы получить доступ к методам, которые мне нужны для соединения узлов и установки значений.Он издавал те звуки, которые я хотел, но мне не нравилось, насколько тесно и многословны мои файлы.

Я все переделал.Теперь есть один файл, который использует аудио контекст, который управляет всеми аудио узлами.Он имеет несколько методов, которые я могу использовать для обновления значений по мере необходимости.У меня также есть карта имен строк для узлов, поэтому я устанавливаю значения следующим образом: setValue('filter', 'frequency', newValue).Есть несколько случаев, которые нужно обрабатывать отдельно (например, кривая искажения), но в целом мне легче читать.Эта абстракция также означает, что ваши аудио узлы не чувствительны к изменениям в иерархиях компонентов.

Это то, что я рекомендую.Вытащите ваши аудио узлы из ваших классов React.Намного проще управлять кодом, который управляет узлами.

...