最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React function returns undefined - Stack Overflow

programmeradmin7浏览0评论

I'm about two weeks into studying React and working on my first SPA. I'm loving react and able to figure out many of my problems but I've run into two problems on this MusicPlayer ponent I'm making.

One is that when I change src in my html audio element the actual audio doesn't change even though the src path does change. I can see it happening in dev tools. I can see the src change when a button is clicked, but the audio that is playing doesn't change. If the audio track finishes it doesn't load the next track. The audio that I hear is always track 1 regardless of what the src is.

My other issue is that songBuilder() is returning undefined. I can't find any bugs in my syntax though they must be there. I used create-react-app as my boilerplate as I don't understand webpack in the slightest yet. Is my map problem a deficit in my JS understanding or is something odd happening with the bundling/build? Please let me know if more information is needed to answer this question. Thank you!

import React, { Component } from "react";

const songRepo = [
  {
    title: "The Silver Swan",
    songLength: "0:13",
    path: require("./songs/thesilverswan.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  }
];

export default class MusicPlayer extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  songBuilder() {
    return songRepo.map((song, index) => (
      <li
        className={index % 2 === 0 ? "even song_wrapper" : "odd song_wrapper"}
      >
        <span className="song_number"> {index + 1}</span>
        <span key={index + 1} className="song_title">
          {song.title}
        </span>
        <span className="song_length">{song.songLength}</span>
      </li>
    ));
  }

  playerClick(type) {
    if (type === "next_song" && this.state.count < songRepo.length - 1) {
      this.setState({ count: this.state.count + 1 });
    } else if (type === "prev_song" && this.state.count > 0) {
      this.setState({ count: this.state.count - 1 });
    }
  }

  render() {
    return (
      <div className="player">
        <div className="player_nav">
          <div className="player_title">
            <span className="song_number">{this.state.count + 1}</span>
            <span className="song_title">
              {songRepo[this.state.count].title}
            </span>
            <span className="song_length">
              {songRepo[this.state.count].songLength}
            </span>
          </div>
          <audio className="waveform" controls="controls">
            <source src={songRepo[this.state.count].path} type="audio/mp3" />
          </audio>
          <div className="player_buttons">
            <span
              className="prev_song"
              onClick={this.playerClick.bind(this, "prev_song")}
            >
              &lsaquo;&lsaquo;
            </span>
            <span> </span>
            <span
              className="next_song"
              onClick={this.playerClick.bind(this, "next_song")}
            >
              &rsaquo;&rsaquo;
            </span>
          </div>
          <div>
            <ul className="song_list">{songBuilder()}</ul>
          </div>
        </div>
      </div>
    );
  }
}

I'm about two weeks into studying React and working on my first SPA. I'm loving react and able to figure out many of my problems but I've run into two problems on this MusicPlayer ponent I'm making.

One is that when I change src in my html audio element the actual audio doesn't change even though the src path does change. I can see it happening in dev tools. I can see the src change when a button is clicked, but the audio that is playing doesn't change. If the audio track finishes it doesn't load the next track. The audio that I hear is always track 1 regardless of what the src is.

My other issue is that songBuilder() is returning undefined. I can't find any bugs in my syntax though they must be there. I used create-react-app as my boilerplate as I don't understand webpack in the slightest yet. Is my map problem a deficit in my JS understanding or is something odd happening with the bundling/build? Please let me know if more information is needed to answer this question. Thank you!

import React, { Component } from "react";

const songRepo = [
  {
    title: "The Silver Swan",
    songLength: "0:13",
    path: require("./songs/thesilverswan.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  },
  {
    title: "Miracle Cure",
    songLength: "0:12",
    path: require("./songs/miraclecure.mp3")
  }
];

export default class MusicPlayer extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  songBuilder() {
    return songRepo.map((song, index) => (
      <li
        className={index % 2 === 0 ? "even song_wrapper" : "odd song_wrapper"}
      >
        <span className="song_number"> {index + 1}</span>
        <span key={index + 1} className="song_title">
          {song.title}
        </span>
        <span className="song_length">{song.songLength}</span>
      </li>
    ));
  }

  playerClick(type) {
    if (type === "next_song" && this.state.count < songRepo.length - 1) {
      this.setState({ count: this.state.count + 1 });
    } else if (type === "prev_song" && this.state.count > 0) {
      this.setState({ count: this.state.count - 1 });
    }
  }

  render() {
    return (
      <div className="player">
        <div className="player_nav">
          <div className="player_title">
            <span className="song_number">{this.state.count + 1}</span>
            <span className="song_title">
              {songRepo[this.state.count].title}
            </span>
            <span className="song_length">
              {songRepo[this.state.count].songLength}
            </span>
          </div>
          <audio className="waveform" controls="controls">
            <source src={songRepo[this.state.count].path} type="audio/mp3" />
          </audio>
          <div className="player_buttons">
            <span
              className="prev_song"
              onClick={this.playerClick.bind(this, "prev_song")}
            >
              &lsaquo;&lsaquo;
            </span>
            <span> </span>
            <span
              className="next_song"
              onClick={this.playerClick.bind(this, "next_song")}
            >
              &rsaquo;&rsaquo;
            </span>
          </div>
          <div>
            <ul className="song_list">{songBuilder()}</ul>
          </div>
        </div>
      </div>
    );
  }
}
Share Improve this question edited Sep 13, 2017 at 6:48 TJK asked Sep 13, 2017 at 6:24 TJKTJK 551 silver badge7 bronze badges 4
  • which function gives undefined? – Vikram Saini Commented Sep 13, 2017 at 6:27
  • @VikramSaini "My other issue is that songBuilder() is returning undefined" – Suraj Rao Commented Sep 13, 2017 at 6:28
  • songBuilder() is invoked towards the bottom nested in a <ul /> – TJK Commented Sep 13, 2017 at 6:29
  • 1 Use this.songBuilder() instead of songBuilder() to refer to the member function of your class. – jlaitio Commented Sep 13, 2017 at 6:32
Add a ment  | 

1 Answer 1

Reset to default 5

try to call this method as

<ul className="song_list">{this.songBuilder}</ul>

initially you called your method as

songBuilder()--returns "undefined" since this points to the window

this.songBuilder--works as this point to current object

If your function is defined within an object, calling it directly from an object will set its context to the object on which the function is being called.

发布评论

评论列表(0)

  1. 暂无评论