我想将反应的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
是异步的。有什么方法可以将结果保存在状态中吗?
答案 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});
}
});