如何使用反应setState与chrome API

时间:2016-11-09 17:32:21

标签: javascript reactjs google-chrome-extension

我想将反应的setState与chrome API一起使用,但我遇到了一个问题......

componentDidMount() {

    chrome.runtime.onMessage.addListener(function(request, sender) {
        if (request.action == "getSource") {
            this.setState({sourceCode: request.source});
        }
    }); 
}

我尝试了以下操作但Chrome API无法将setState识别为函数,因此我尝试先将request.source保存为变量...

componentDidMount() {
    var source = "";
    chrome.runtime.onMessage.addListener(function(request, sender) {
        if (request.action == "getSource") {
            source = request.source;
        }
    });
    this.setState({sourceCode: source});
}

但是当我尝试以下操作时,source仍为空字符串。我无法弄清楚为什么source被设置为request.source。我该如何解决这个问题?

修改

我正在调用脚本......

chrome.tabs.executeScript(null, {
        file: 'src/js/scripts/getPageSource.js'
     }, function() {
     ...

并在脚本中我有以下内容......

chrome.runtime.sendMessage({
    action: "getSource",
    source: DOMtoString(document)
});

其中DOMtoString函数只返回一个字符串。它是由componentDidMount抓住的,我通过在if语句中打印到控制台来验证。

我注意到addListener是异步的。有什么方法可以将结果保存在状态中吗?

1 个答案:

答案 0 :(得分:3)

您需要绑定this,以便在事件侦听器

中保持不变
chrome.runtime.onMessage.addListener(function(request, sender) {
    if (request.action == "getSource") {
        this.setState({sourceCode: request.source});
    }
}.bind(this));

您的第二次尝试不起作用,因为回调是异步的。回调返回时需要调用setState。在第二次尝试中,您注册了监听器,但立即调用setState。

编辑: 或者,您可以切换为使用arrow functions。这将在词法上绑定this,因此它将保持不变。

chrome.runtime.onMessage.addListener((request, sender) => {
    if (request.action == "getSource") {
        this.setState({sourceCode: request.source});
    }
});