react中销毁报错:调用已卸载组件上的setstate?

在我从一个页面点击跳转到另一个页面,就开始一直出现这个错误

setState(…):只能更新已安装或安装的组件。这通常意味着您调用卸载组件上的setState()。这是一个空操作。请检查Player组件的代码。
图片描述

Player.js代码

import React from 'react'
import Progress from '../components/progress'
import './player.less'
import { Link } from 'react-router'
import PubSub from 'pubsub-js'

//音频总时长
let duration = null;

let Player = React.createClass({

// 设置初始数据
getInitialState() {
    return {
        progress: 0,
        volume: 0,
        isPlay: true,
        leftTime: ''
    }
},
/**
 * 事件发布
 */
playPrev() {
    PubSub.publish('PLAY_PREV');
},
playNext() {
    PubSub.publish('PLAY_NEXT');
},
//时间格式化
formatTime(time) {
    time = Math.floor(time);
    let minutes = Math.floor(time / 60);
    let seconds = Math.floor(time % 60);

    // seconds =seconds < 10 ? `0${seconds}` : seconds;
    // return `${minutes}:${seconds}`;
    return minutes + ':' + (seconds < 10 ? '0' + seconds : seconds);
},
componentDidMount() {
    // 监听音乐播放时间
    $('#player').bind($.jPlayer.event.timeupdate, (e) => {
        //音频总时长
        duration = e.jPlayer.status.duration;
        //回调函数,将音乐播放时间传回progress
        this.setState({
            volume: e.jPlayer.options.volume * 100,      //音量
            progress: e.jPlayer.status.currentPercentAbsolute,   //播放时间百分比
            leftTime: this.formatTime(duration * (1 - e.jPlayer.status.currentPercentAbsolute / 100))
        });
    });
},
//解绑
componentWillUnMount() {
    $('#Player').unbind($.jPlayer.event.timeupdate);
},
progressChangeHandler(progress) {
    //调用jPlayer的方法,更改播放时间
    // this.state.isPlay ? 'play' : 'pause'
    $('#player').jPlayer("play",duration * progress);

    this.setState({
        isPlay: true
    });
},
//音量调节
changeVolumeHandler(progress) {
    $('#player').jPlayer('volume',progress);

    // this.setState({
    //     volume: progress * 100,
    // });
},
//播放和暂停
play() {
    if(this.state.isPlay) {
        $('#player').jPlayer('pause');
    } else {
        $('#player').jPlayer('play');
    }

    this.setState({
        isPlay: !this.state.isPlay
    });
},
render() {
    return (
            //html代码
        );
} 

});

路由设置代码
let Root = React.createClass({

render() {
    return (
    <Router history={hashHistory}>
        {/* 根据路径选择所要渲染的组件 */}
        <Route path="/" component={App}>
            <IndexRoute component={Player}></IndexRoute>
            <Route path="/list" component={MusicList}></Route>
            <Route path="/detail" component={MusicDetail}></Route>
        </Route>
    </Router>
    );
}

});

阅读 4.8k
1 个回答

你没有解绑成功,应该给函数设置一个引用,然后unbind的时候要传入这个引用作为第二个参数

// 设置初始数据
getInitialState() {
    return {
        progress: 0,
        volume: 0,
        isPlay: true,
        leftTime: ''
    }
},
/**
 * 事件发布
 */
playPrev() {
    PubSub.publish('PLAY_PREV');
},
playNext() {
    PubSub.publish('PLAY_NEXT');
},
//时间格式化
formatTime(time) {
    time = Math.floor(time);
    let minutes = Math.floor(time / 60);
    let seconds = Math.floor(time % 60);

    // seconds =seconds < 10 ? `0${seconds}` : seconds;
    // return `${minutes}:${seconds}`;
    return minutes + ':' + (seconds < 10 ? '0' + seconds : seconds);
},
jPEvent = (e) => {
        //音频总时长
        duration = e.jPlayer.status.duration;
        //回调函数,将音乐播放时间传回progress
        this.setState({
            volume: e.jPlayer.options.volume * 100,      //音量
            progress: e.jPlayer.status.currentPercentAbsolute,   //播放时间百分比
            leftTime: this.formatTime(duration * (1 - e.jPlayer.status.currentPercentAbsolute / 100))
        });
    }
componentDidMount() {
    // 监听音乐播放时间
    $('#player').bind($.jPlayer.event.timeupdate, this.jPEvent);
},
//解绑
componentWillUnMount() {
    $('#Player').unbind($.jPlayer.event.timeupdate, this.jPEvent);
},
progressChangeHandler(progress) {
    //调用jPlayer的方法,更改播放时间
    // this.state.isPlay ? 'play' : 'pause'
    $('#player').jPlayer("play",duration * progress);

    this.setState({
        isPlay: true
    });
},
//音量调节
changeVolumeHandler(progress) {
    $('#player').jPlayer('volume',progress);

    // this.setState({
    //     volume: progress * 100,
    // });
},
//播放和暂停
play() {
    if(this.state.isPlay) {
        $('#player').jPlayer('pause');
    } else {
        $('#player').jPlayer('play');
    }

    this.setState({
        isPlay: !this.state.isPlay
    });
},
render() {
    return (
            //html代码
        );
} 

代码没格式化不知道会不会缺个括号什么的,大概就这个意思。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题