如何在 chrome API 中使用 react setState

IT技术 javascript reactjs google-chrome-extension
2021-04-30 22:12:00

我想将 reactsetState与 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)
});

whereDOMtoString函数只返回一个字符串。这是我componentDidMount通过在 if 语句中打印到控制台来验证的。

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

1个回答

您需要绑定,this以便在事件侦听器中保持不变

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

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

编辑:或者,您可以改用箭头功能这将在词法上绑定,this因此它将保持不变。

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