简体   繁体   English

React.js Chrome 扩展 - 如何将 Background.js 中的数据存储在 React 内部的变量中?

[英]React.js Chrome Extension - How to store data from Background.js in a variable inside React?

Hello what I am trying to do is send a string that I derived from my background.js file and send it to my react app (specifically a component used by App.js).您好,我要做的是发送一个从我的 background.js 文件派生的字符串并将其发送到我的反应应用程序(特别是 App.js 使用的组件)。 I have /* global chrome */ at the top of the component.js file and am able to store data on the chrome local storage however my question is how do I make sure that I can store this data in a variable before the React app is processed?我在 component.js 文件的顶部有 /* global chrome */ 并且能够将数据存储在 chrome 本地存储上但是我的问题是如何确保我可以在 React 应用程序之前将这些数据存储在一个变量中被处理了吗? For example, even though I am able to assign a variable inside the component the data from chrome storage, it is only stored after my React app is created.例如,即使我能够在组件内部为 chrome 存储中的数据分配一个变量,它也只会在我的 React 应用程序创建后存储。 What I'm trying now is to send a chrome message in background.js and try to listen for this message in the component to store the variable however the listener does not seem to be working.我现在尝试的是在 background.js 中发送一条 chrome 消息,并尝试在组件中侦听此消息以存储变量,但是侦听器似乎没有工作。 Any help would be appreciated.任何帮助,将不胜感激。 (ps this is using functional components but help in class components would also be appreciated) (ps这是使用功能组件,但对 class 组件的帮助也将不胜感激)

component.js:组件.js:

chrome.runtime.onMessage.addListener(function(msg) { 
   if(msg.type == "USER_STORED") {
      chrome.storage.local.get(['name'], function(result) { 
         console.log("User is " + result.name); 
         username = result.name; 
      }); 
   }
});

background.js:背景.js:

chrome.storage.local.set({name: username}, function() { 
      console.log("User is set to " + username);
      chrome.runtime.sendMessage({type: "USER_STORED" });
      console.log("message sent"); 
    }); 

    // Open extension window
    console.log("WINDOW_OPENED"); 
    var win = window.open("index.html", "extension_popup"); 

Console: Extension console image控制台:扩展控制台图像

You use wrong approach.你使用了错误的方法。 You don't need to send such messages from background at all, nor need to listen for them in your popup window.您根本不需要从后台发送此类消息,也不需要在弹出窗口 window 中收听它们。 Just add chrome.storage.local.get call into your popup entry point (likely index.js ) and wrap ReactDOM.render with its callback.只需将chrome.storage.local.get调用添加到您的弹出入口点(可能是index.js )并使用其回调包装ReactDOM.render Something like this:像这样的东西:

chrome.storage.local.get(null, function (data) {
  ReactDOM.render(
    <App {...data} />,
    document.getElementById('root')
  )
});

Then, the data from chrome.storage will be available in all sub-components of the root <App> via props.然后,来自chrome.storage的数据将通过 props 在根<App>的所有子组件中可用。 Something like this:像这样的东西:

function YourComponent(props) {
  console.log("User is " + props.name);
  return <h1>Hello, {props.name}</h1>;
}

I think you can directly access the chrome storage API inside the componentDidMount() method and fetch the variable from the storage.get() and set the value to a state variable.我认为您可以在 componentDidMount() 方法中直接访问 chrome 存储 API 并从 storage.get() 获取变量并将值设置为 state 变量。

Try this尝试这个

manifest.json manifest.json

{
    "name": "test2",
    "version": "0.0.1",
    "manifest_version": 2,
    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
    "background": {
        "scripts": [
            "./background/background.bundle.js"
        ]
    },
    "permissions": [
        "storage",
        "tabs",
        "activeTab"
    ],
    "browser_action": {}
}

background.js背景.js

console.log("inside bg script")
let user = "zzzzzzzzz"
chrome.storage.local.set({ name: user }, function () {
    console.log("User is set to" + user);
})
chrome.browserAction.onClicked.addListener((tab) => {
    chrome.tabs.create({
        url: chrome.runtime.getURL("./test.html")
    });
});

test.html测试.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app-root">
    </div>
    <script src="./index.bundle.js"></script>
</body>
</html>

index.js (react component) index.js (反应组件)

import React from "react";
import ReactDOM from "react-dom";
class MainApp extends React.Component {
    render() {
        return (
            <div>
                <h1>hi</h1>
            </div>
        );
    }
    componentDidMount() {
        let newThis = this;
        chrome.storage.local.get(['name'], function (result) {
            console.log("User is " + result.name);
// you can use the variable or set to any state variable from here
        });
    }
}
ReactDOM.render(<MainApp />, document.getElementById("app-root"))

the required value will be available in the componentDidMount() functions storage.get() methods callback.所需的值将在 componentDidMount() 函数 storage.get() 方法回调中可用。 You can set to the component state variable or use it as your wish.您可以设置组件 state 变量或根据需要使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM