简体   繁体   English

在 Chrome 扩展中将 React 组件注入页面的正确方法?

[英]Proper way to inject React Component onto page in Chrome Extension?

I am making a Chrome Extension and I want to inject HTML into the page DOM using the content scripts.我正在制作一个 Chrome 扩展程序,我想使用内容脚本将 HTML 注入页面 DOM。 That is easy, but I also want the content script to be a React component and the JS itself does not need to interact with the page JavaScript context, so that makes it simpler.这很容易,但我还希望内容脚本是一个 React 组件,并且 JS 本身不需要与页面 JavaScript 上下文交互,这样就更简单了。 I have a simple way to inject a container element into the DOM that my React code can render to, but I feel like it is very hacky and so I was wondering if there was an official way that React developers could suggest (Google was not particularly useful on this specific matter).我有一种简单的方法可以将容器元素注入到我的 React 代码可以渲染到的 DOM 中,但我觉得它非常 hacky,所以我想知道 React 开发人员是否可以建议一种官方方式(谷歌不是特别对这个具体问题有用)。

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <h1>App was injected.</h1>
  }
};

let container = document.createElement('div');
container.setAttribute("id", "app-wrapper");
document.body.appendChild($el);

ReactDOM.render(
  <App/>, container);

I've found there's broadly two ways to do it.我发现大致有两种方法可以做到。 Both involve creating a new element somewhere in the <body> and attaching the ReactDom.render call to it.两者都涉及在<body>某处创建一个新元素并将ReactDom.render调用附加到它。

  1. Using content scripts - but this can be a headache for React (ejecting create-react-app and managing webpack)使用内容脚本 - 但这对 React 来说可能是一个头疼的问题(弹出 create-react-app 和管理 webpack)
  2. Injecting the code directly from the Background.js script when a tab is active. Injecting the code directly from the Background.js script when a tab is active. To do this you can use chrome.tabs.executeScript .为此,您可以使用chrome.tabs.executeScript There is a short blog on it here: https://dev.to/anobjectisa/build-a-chrome-extension-using-reactjs-38o7这里有一个简短的博客: https : //dev.to/anobjectisa/build-a-chrome-extension-using-reactjs-38o7

Usually it's split into 2 files, one HTML and one JS.通常它被分成 2 个文件,一个 HTML 和一个 JS。 Something like this:像这样的东西:

index.html索引.html

<head>
  <script src="path/to/bundle.js"></script>
</head>
<body>
  <div id="app-wrapper" />
</body>

App.js应用程序.js

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <h1>App was injected.</h1>
  }
};

ReactDOM.render(
  <App/>, document.getElementById("app-wrapper"));

I don't know about an official way, but this is the implementation found in create-react-app and most of tutorials around.我不知道官方方法,但这是在create-react-app和大多数教程中找到的实现。

This solution is based on: https://github.com/yosevu/react-content-script .该解决方案基于: https://github.com/yosevu/react-content-script


Inside App.js : App.js内部:

import React from 'react';

function App() {
  return (
    <>
      <h1>Hello World</h1>
    </>
  )
}

export default App;

Inside content.js :内部content.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App'

const body = document.querySelector('body')
const app = document.createElement('div')

app.id = 'react-root'

if (body) {
  body.prepend(app)
}

const container = document.getElementById('react-root');
const root = createRoot(container);

root.render(<App/>)  // Render react component

Result:结果:

在此处输入图像描述

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

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