反应:_this2.setState不是一个函数

时间:2018-07-05 20:01:10

标签: javascript reactjs

我正在使用React开发语音控制的幻灯片放映(幻灯片是iframe)。我有一个工作版本(它将循环播放幻灯片,用于上一个/下一个幻灯片工作的语音命令...),但是当我尝试添加一个命令来暂停幻灯片放映循环时,出现以下错误。我的“下一张幻灯片”命令有效,并且与“暂停循环”命令没什么不同,所以我不明白为什么“暂停循环”命令会产生错误。

这是我的第一个React应用程序,任何帮助将不胜感激。

错误:

Unhandled Rejection (TypeError): _this2.setState is not a function

   | .then(res => res.json())
   | .then(
   |    (result) => {
>  |        this.setState({
   |            speechRecogStatus: result.speech_recog_status
   |        });

代码:

这只是代码的一部分,并且已被修改为删除不相关的行。

在App.js中

import nextSlideCommand from './commands/next-slide';
import pauseLoopCommand from './commands/pause-loop';
import SlideList from './slide-list.json';

class App extends Component {
    constructor(props) {
        super(props);

        this.fetchingMasterSwitchStatus = false;

        let initialSlideKeyword = SlideList.loop[0].keyword;

        this.state = {
            speechRecogStatus: "off",
            iframeSrc: SlideList.list[initialSlideKeyword].url,
            pageTitle: SlideList.list[initialSlideKeyword].title,
            loopIndex: 0,
            loopIsPlaying: true,
            iframeStyle: {visibility: 'hidden'},
        };

        if (annyang) {

            // define voice commands
            let commands = {
                'next slide': () => {
                    nextSlideCommand.call(this, SlideList);
                },
                'pause loop': () => {
                    pauseLoopCommand.call(this, SlideList);
                },
            };

            // Add our commands to annyang
            annyang.addCommands(commands);
        }

        // suggested by another StackOverflow post on 
        // this error - doesn't solve my problem
        this.getMasterSwitchStatus = this.getMasterSwitchStatus.bind(this);
        this.iframeOnLoad = this.iframeOnLoad.bind(this);
    }

    getMasterSwitchStatus() {

        // query an online JSON file periodically to determine whether this 
        // app should be listening for voice commands or not

        if (this.fetchingMasterSwitchStatus) return;

        this.fetchingMasterSwitchStatus = true;
        fetch("JSON_URL")
            .then(res => res.json())
            .then(
                (result) => {
                    this.setState({
                        speechRecogStatus: result.speech_recog_status
                    });

                    let status = (annyang.isListening()) ? "on" : "off";
                    if (status === result.speech_recog_status) {
                        this.fetchingMasterSwitchStatus = false;
                        return;
                    }

                    if (result.speech_recog_status === 'on') {
                        annyang.resume();
                    } else {
                        annyang.abort();
                    }
                    this.fetchingMasterSwitchStatus = false;
                },
                (error) => {
                    this.fetchingMasterSwitchStatus = false;
                }
            );
    }

    componentDidMount() {
        setInterval(
            () => {
                this.getMasterSwitchStatus();
            },
            CHECK_MASTERSWTICH_FREQ
        );
    }

    iframeOnLoad() {
        this.setState({
            iframeStyle: {visibility: 'visible'}
        });

        setTimeout(
            () => {
                if (!this.state.loopIsPlaying) return;
                utilFunctions.nextSlide(this, SlideList)
            },
            SlideList.loop[this.state.loopIndex].dwell * 1000
        );
    }

    render() {
        return [
            <div key="content" className="content">
                <Iframe key="iframe" src={this.state.iframeSrc} 
                        iframeStyle={this.state.iframeStyle}
                        onLoadFun={() => this.iframeOnLoad()}/>
            </div>
        ];
    }

}

export default App;

commands/pause-loop.js

let pauseLoopCommand = function(SlideList) {
    this.setState = ({
        loopIsPlaying: false
    });
};

export default pauseLoopCommand;

在commands / next-slide.js中

let nextSlideCommand = function(SlideList) {
    // calculate new loop index
    let index = context.state.loopIndex;
    index++;
    if (index > SlideList.loop.length - 1) {
        index = 0;
    }
    let keywords = SlideList.loop[index].keyword;

    // ok, change slide
    this.setState({
        loopIndex: index,
        iframeSrc: SlideList.list[keywords].url,
        pageTitle: SlideList.list[keywords].title,
        iframeStyle: {visibility: 'hidden'},
    });
};

export default nextSlideCommand;

2 个答案:

答案 0 :(得分:1)

根据@Tholle的评论,这是我的pauseLoopCommand()函数中令人反感的行:

this.setState = ({
    loopIsPlaying: false
});

这应该是:

this.setState({
    loopIsPlaying: false
});

答案 1 :(得分:1)

您的pauseLoopCommand函数正在为this.setState分配一个新值,因此将来的this.setState调用将尝试将该新对象作为函数调用,这会引起您的错误。 / p>

如果您像在其他所有地方一样调用函数,则错误应该消失。

let pauseLoopCommand = function(SlideList) {
    this.setState({
        loopIsPlaying: false
    });
};

export default pauseLoopCommand;