【问题标题】:How to use react setState with chrome API如何使用带有 chrome API 的 react setState
【发布时间】:2017-03-23 14:36:04
【问题描述】:

我想将 react 的 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 是异步的。有什么办法可以将结果保存在状态中?

【问题讨论】:

  • edit 成为主题的问题:包括一个完整 minimal reproducible example 重复该问题。包括一个manifest.json,一些后台内容脚本。寻求调试帮助的问题(“为什么这段代码不工作?”)必须包括:►期望的行为,►特定问题或错误►必要的最短代码重现它在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:“如何创建 minimal reproducible example”、What topics can I ask about here?How to Ask
  • 你知道 setState 是异步的吗?如果你想看到结果,你必须在 setState() 的回调函数中询问它们。即:this.setState({sourceCode: source}, function(){ console.log(this.state.sourceCode) })
  • 我们需要看看你是如何发送 source 的以及其中的内容很明显:-) 另外,是的,正如 Falk 所说,你错误地使用了异步 js。
  • 我认为这完全是主题,不知道为什么会被标记。无论如何,您都会遇到两个经典的 javascript 问题。 1) setState 不是一个函数,因为 this 正在被您的回调函数 stackoverflow.com/questions/31045716/… 反弹,并且 2) source 是一个空字符串,因为您的 setstate 调用将在您上面的回调函数之前触发

标签: javascript reactjs google-chrome-extension


【解决方案1】:

你需要绑定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});
    }
});

【讨论】:

  • 你正在使用 react 和 JSX - 更容易使用 =>
  • 同意。我会在您的答案中添加=> 作为选项。
  • 我更喜欢 KISS 方法,但将其添加为一个选项。
  • @BenjaminGruenbaum,不,反应和 JSX 不是原因。 => 可用,因为它作为 Chrome 扩展程序运行。因此,您只需将 Chrome 视为支持 =>(从 v45 开始)的浏览器。此外,其他可能兼容此类扩展的浏览器(例如 Firefox WebExtension)也支持=>
  • @Makyen 我认为 Benjamin 是在暗示 OP 可能已经在使用 babel 进行编译,所以实际上编译后的代码中不会存在箭头函数。
猜你喜欢
  • 2017-04-29
  • 2020-08-30
  • 2020-07-24
  • 1970-01-01
  • 2019-06-16
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多