反应状态值未定义

时间:2019-06-08 20:24:54

标签: javascript reactjs state

我正在构建一个音乐播放器应用,并且我有一个函数可以在组件状态下从对象获取值。

当我将该值赋予函数时,它会打印未定义的值,而不是值本身,因此该函数无法使用未定义的值。

这是我在打印状态时firstSong组件的外观:

{
    Title: "One Dance",
    Artist: "Drake",
    Length: "4:03",
    Path:
      "/home/songs/Drake - One Dance ft. EMØ.mp3"
  }

这是完整的组件代码:

import React, { Component } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faBackward,
  faPlay,
  faForward,
  faStop
} from "@fortawesome/free-solid-svg-icons";
import styled from "styled-components";
import axios from "axios";

const CardStyling = styled.div`
  .card-body {
    width: 100%;
  }

  #song-header {
    margin-bottom: 25px;
  }

  #artist {
    margin-bottom: 25px;
  }

  #time {
    margin-bottom: 25px;
  }
`;

let display = "none";
const firstSongApi = "http://localhost:4001/getFirstSong";
const playSongApi = "http://localhost:4001/playSong";

export default class SongInfo extends Component {
  constructor() {
    super();
    this.state = {
      firstSong: this.getFirstSong(firstSongApi),
      isPlaying: false
    };
  }

  getFirstSong = async firstSongApi => {
    const request = await axios({
      method: "get",
      url: firstSongApi,
      headers: {}
    });
    try {
      let firstSong = request.data.firstSong;
      this.setState({
        firstSong: firstSong
      });
    } catch (error) {
      console.error(error);
    }
  };

  playOrPauseSong = path => {
    console.log(path);
  };

  render() {
    {
      this.playOrPauseSong(this.state.firstSong.path);
    }
    return (
      <CardStyling className="card">
        <div className="card-body">
          <h3 id="song-header">{this.state.firstSong.Title}</h3>
          <h5 id="artist">By: {this.state.firstSong.Artist}</h5>
          <h5 id="Time">{this.state.firstSong.Length}</h5>
          <button type="button" id="back-btn" className="btn">
            <FontAwesomeIcon icon={faBackward} />
          </button>
          <button
            type="button"
            id="play-btn"
            className="btn"
            onClick={() => this.playOrPauseSong(this.state.songLocation)}
          >
            <FontAwesomeIcon icon={faPlay} />
          </button>
          <button
            type="button"
            id="stop-btn"
            className="btn"
            style={{ display: display }}
          >
            <FontAwesomeIcon icon={faStop} />
          </button>
          <button type="button" id="next-btn" className="btn">
            <FontAwesomeIcon icon={faForward} />
          </button>
        </div>
      </CardStyling>
    );
  }
}


我希望该函数获取真实的路径值而不是未定义的值,谢谢!

2 个答案:

答案 0 :(得分:1)

确保您的状态如下所示,并且路径将在playOrPauseSong内部正确记录;

    this.state = {
      firstSong: {
        title: "One Dance",
        artist: "Drake",
        length: "4:03",
        path:
          "/home/songs/Drake - One Dance ft. EMØ.mp3"
      }
    }


  playOrPauseSong = path => {
    console.log(path)
  }

  render(){

    return(
      <div>
        {this.playOrPauseSong(this.state.firstSong.path)}
      </div>
    )
  }

答案 1 :(得分:0)

render() {
    {
      this.playOrPauseSong(this.state.firstSong.path);
    }
...

不确定的原因是您的firstSong仍在进行网络请求,这是async方法,因此不会有firstSongfirstSong.path,因此是{ {1}}。因此,您可以更新为关注

undefined

所以它的作用是,当没有render() { { this.state.firstSong.path && this.playOrPauseSong(this.state.firstSong.path); } 时,该方法将不会被调用,并且当您的网络调用返回结果时,它将被调用,但是实际上,您应该在其中引入另一个标志跳过调用path,因为您的组件将不断重新渲染,并且您不想在每次重新渲染时都继续调用它

更新

让我们重组一下

我们可以将this.playOrPauseSong的初始状态设置为firstSong,并分别调用getFirstSong,因此您的构造函数应如下所示

null

然后对于您的constructor() { super(); this.state = { firstSong: null, isPlaying: false }; this.getFirstSong(firstSongApi); } 方法,您要检查render,因为在初始加载时,firstSong为空,因此请更新以下内容

firstSong
相关问题