将mp3添加到React

时间:2019-07-16 03:46:06

标签: javascript reactjs

我在Create React App引导的项目的src文件夹中添加了mp3。我为音频文件Audio.js添加了一个组件,我希望根据道具https://graph.microsoft.com/v1.0/groups/[GroupID]/threads/[ConversationID]/posts 是否正确来有条件地播放该组件。 父App.js将道具传递给子Timer.js,后者呈现Audio.js。

Audio.js文件为我定义了“反应”,但从未使用过错误,我不确定为什么。

Audio.js:

playAlarm

在Timer.js中,音频呈现如下:import React, { Component } from 'react'; class Audio extends Component { constructor() { super(); this.url = "./chime.mp3"; this.audio = new Audio(this.url); } render() { return ( this.audio ); } } export default Audio;

当我测试播放音频时,当playAlarm设置为true时,我得到Uncaught RangeError:在Audio.js中,与super()所在的行超过了最大调用堆栈大小。

App.js:

{props.playAlarm ? <Audio /> : null}

导出默认应用;

这也是Timer.js:

import React, { Component } from 'react';
import Timer from './Timer';

class App extends Component {
  // ES6 class property/class field syntax allows you to remove constructor when just being used to initialize state
  state = {
    sessionDuration: 5, // TODO: change back to 1500 when testing done
    breakDuration: 3, // TODO: change back to 300 when testing done
    sessionTimeRemaining: 5, // TODO: change back to 1500 when testing done
    breakTimeRemaining: 3, // TODO: change back to 300 when testing done
    isSession: true,
    timerOn: false,
    sessionNumber: 0,
    playAlarm: false
  }

  // Using property initializer syntax to avoid need to bind, since arrow functions don't create their own this context and use value of enclosing context instead. transform-class-properties Babel plugin necessary to use this syntax (included in Create React App). Refer to https://itnext.io/property-initializers-what-why-and-how-to-use-it-5615210474a3 for more details

  // DURATION CHANGES

  decreaseBreakDuration = () => {
    // Conditional statement prevents decrease when break is at 1 minute
    if (this.state.breakDuration === 60) {
      return undefined;
    } else {
      this.setState({
        breakDuration: this.state.breakDuration - 60
      });
    }
  }

  increaseBreakDuration = () => {
    this.setState({
      breakDuration: this.state.breakDuration + 60
    });
  }

  decreaseSessionDuration = () => {
    // Conditional statement prevents decrease when session is at 5 minutes
    if (this.state.sessionDuration === 300) {
      return undefined;
    } else {
      this.setState({
        sessionDuration: this.state.sessionDuration - 60,
        sessionTimeRemaining: this.state.sessionTimeRemaining - 60
      });
    }
  }

  increaseSessionDuration = () => {
    this.setState({
      sessionDuration: this.state.sessionDuration + 60,
      sessionTimeRemaining: this.state.sessionTimeRemaining + 60
    });
  }

  manageBreak = () => {
    this.setState({
      playAlarm: false
    });
    this.time = setInterval(() => {
      this.setState({
        breakTimeRemaining: this.state.breakTimeRemaining - 1
      });
      if (this.state.breakTimeRemaining === 0) {
        this.handleBreakComplete();
      }
    }, 1000);
  }

  manageSession = () => {
    this.setState({
      playAlarm: false
    });
    // Every 1,000 ms (1 second), subtract 1 (a single second) from displayed sessionTimeRemaining. Assigned to this.time (scoped to entire class) in order to pass it to clearInterval() when pause button is clicked
    this.time = setInterval(() => {
      this.setState({
        sessionTimeRemaining: this.state.sessionTimeRemaining - 1
      });
      if (this.state.sessionTimeRemaining === 0) {
        this.handleSessionComplete();
      }
    }, 1000);
  }

  handleSessionComplete = () => {
    clearInterval(this.time);
    this.setState({
      playAlarm: true,
      sessionNumber: this.state.sessionNumber + 1
    })

    if (this.state.sessionNumber === 4) {
      this.handlePomodoroCycleDone();
    } else {
      this.setState({
        timerOn: false,
        sessionTimeRemaining: this.state.sessionDuration,
        breakTimeRemaining: this.state.breakDuration,
        isSession: !this.state.isSession,
      });
    }
  }

  handlePomodoroCycleDone = () => {
    // TODO: Display message in modal
    console.log('Great work! You finished a pomodoro cycle (four sessions). Time to relax.')
    // Change back to default values
    this.setState({
      isSession: true,
      timerOn: false,
      sessionDuration: 5, // TODO: change back to 1500
      breakDuration: 3, // TODO: change back to 300 when testing done
      sessionTimeRemaining: 5, // TODO: change back to 1500
    });
  }

  handleBreakComplete = () => {
    clearInterval(this.time);
    this.setState({
      timerOn: false,
      sessionTimeRemaining: this.state.sessionDuration,
      breakTimeRemaining: this.state.breakDuration,
      isSession: !this.state.isSession,
      playAlarm: true
    });
  }

  // PLAY, PAUSE, RESTART BUTTONS

  startTimer = () => {
    this.setState({
      timerOn: true,
    });

    if (this.state.isSession) {
      this.manageSession();
    } else {
      this.manageBreak();
    }
  }

  pauseTimer = () => {
    // Stops setInterval's calling its (setState) callback every 1000 ms
    clearInterval(this.time);

    this.setState({
      timerOn: false
    });
  }

  resetTimer = () => {
  // Stops setInterval's calling its (setState) callback every 1000 ms
  // TODO: Display 4 unchecked circle icons again
    clearInterval(this.time);
    this.setState({
      timerOn: false,
      sessionDuration: 5, // TODO: change back to 1500
      breakDuration: 3, // TODO: change back to 300 when testing done
      sessionTimeRemaining: 5, // TODO: change back to 1500
      breakTimeRemaining: 3, // TODO: change back to 300 when testing done
      sessionNumber: 0
    });
  }

  render() {
    return (
      <Timer
        breakDuration={this.state.breakDuration}
        sessionDuration={this.state.sessionDuration}

        decreaseBreakDuration={this.decreaseBreakDuration}
        increaseBreakDuration={this.increaseBreakDuration}
        decreaseSessionDuration={this.decreaseSessionDuration}
        increaseSessionDuration={this.increaseSessionDuration}

        sessionTimeRemaining={this.state.sessionTimeRemaining}
        breakTimeRemaining={this.state.breakTimeRemaining}
        timerOn={this.state.timerOn}
        sessionNumber={this.state.sessionNumber}

        isSession={this.state.isSession}

        startTimer={this.startTimer}
        pauseTimer={this.pauseTimer}
        resetTimer={this.resetTimer}

        playAlarm={this.state.playAlarm}
      />
    );
  };
}

1 个答案:

答案 0 :(得分:2)

我不了解这里发生的所有事情。但是乍一看,这是一个问题:

class Audio extends Component {
  constructor() {
    super();
    this.url = "./chime.mp3";
    this.audio = new Audio(this.url);
  }

  render() {

    return (
      this.audio
    );
  }
}

超出调用堆栈错误是因为您正在进入无限循环。您在Audio内部实例化Audio,这将使另一个Audio对象,依此类推,直到无穷大。