在 Chrome Extension React 应用中更新状态

Update State within Chrome Extension React app

我已经使用 create-react-app 构建了一个 chrome 扩展来解析当前页面的 HTML 并获取 HTML 中相关图标的数量。

我能够在 chrome 上成功构建和 运行 扩展,但是当我尝试在 Chrome 选项卡脚本中更新状态时出现错误。

这是我的代码:

    /*global chrome*/
import './App.css';
import React, {useState, useEffect} from 'react';

function App() {

  let [poorAccess, setPA] = useState();
  let [mediumAccess, setMA] = useState();
  let [highAccess, setHA] = useState();
  let [perfectAccess, setperfA] = useState();


   
    let dispScripts = () => {
      let theAccess = []
      let poorAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-low ally-instructor-feedback");
      let mediumAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-medium ally-instructor-feedback");
      let highAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-high ally-instructor-feedback");
      let perfectAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-perfect ally-instructor-feedback");
      setPA(poorAccesse.length);
      setMA(mediumAccesse.length);
      setHA(highAccesse.length);
      setperfA(perfectAccesse.length);
    }

    let grabScores = () => { 
    chrome.tabs.executeScript({code: `(${dispScripts})()`})
    }
  return (
    <div className="App">
    <button onClick={grabScores}>Parse</button>
    </div>
  );
}

export default App;

它给我一个错误:

VM3495:1 Uncaught ReferenceError: l is not defined

当我点击我的按钮时。

那么我将如何在 chrome 脚本中更新状态?这甚至可能吗?

找到答案:

由于 Chrome api 的异步性质,您必须这样做:

let dispScripts = () => {
      let theAccess = []
      let poorAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-low ally-instructor-feedback");
      let mediumAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-medium ally-instructor-feedback");
      let highAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-high ally-instructor-feedback");
      let perfectAccesse = document.getElementsByClassName("ally-accessibility-score-indicator ally-accessibility-score-indicator-perfect ally-instructor-feedback");
      // setPA(poorAccesse.length);
      // setMA(mediumAccesse.length);
      // setHA(highAccesse.length);
      // setperfA(perfectAccesse.length);
      return poorAccesse.length;
    }

然后在回调中发送 return 值:


let grabScores = () => { 
    chrome.tabs.executeScript({code: `(${dispScripts})()`}, function(result){
      setPA(result)
    })
    }

executeScript 在网页中运行代码,这是一个不同的页面,因此它没有您的扩展页面中的功能,例如 setPA、setMA 等。

如果他们在扩展 page/popup 中更改了 React 应用程序的状态,则拆分您注入的代码,使其仅 returns executeScript 回调中的数据。数据必须 JSON 兼容:数字、字符串、布尔值、空值,或 array/object 在任何嵌套级别仅包含这些类型。

// this runs in the web page as a content script
const dispScriptsStr = `(${() => {
  return ['low', 'medium', 'high', 'perfect']
    .map(s => document.getElementsByClassName(
      'ally-accessibility-score-indicator' +
      ' ally-accessibility-score-indicator-' + s +
      ' ally-instructor-feedback').length);
}})()`;

// this runs in the extension page, including the callback
const grabScores = () => {
  chrome.tabs.executeScript({code: dispScriptsStr}, results => {
    if (!chrome.runtime.lastError) {
      const res = results[0];
      setPA(res[0]);
      setMA(res[1]);
      setHA(res[2]);
      setperfA(res[3]);
    }
  });
};

但是如果你想在网页中使用这些功能那么你当然需要将它们添加到注入的代码字符串中。