Скажите фоновый скрипт, когда контентный скрипт внедряется с помощью React? - PullRequest
0 голосов
/ 13 февраля 2019

Я внедряю компонент React в веб-страницу как скрипт, но это на странице, которая открывается с помощью фонового скрипта.

Я пытаюсь подождать, пока страница загрузитсяи компонент React монтируется, затем отправьте сообщение этому компоненту.К сожалению, я не могу заставить это работать, поэтому я подозреваю, что это потому, что Chrome говорит, что страница загружена, но компонент React еще не смонтирован.

В моем фоновом скрипте у меня есть следующее:

function relist(request) {
    const url = 'domain.com';
    chrome.tabs.create({ url },() => {
        chrome.tabs.onUpdated.addListener(reListener);
    });
    // Listen for new relist tab and remove listener when loaded
    function reListener(tabId, info, tab) {
        if(tab.url === url && tab.status === "complete") {
            console.log("Found tab");
            chrome.tabs.sendMessage(tab.id, {action: "relist", data: request.data});
            chrome.tabs.onUpdated.removeListener(reListener);
        }
    }
}

Затем в компоненте, который я ввожу, у меня есть следующее:

componentDidMount() {
    console.log("Mounted Design Upload");
    chrome.runtime.onMessage.addListener(
        (request) => {
            console.log("Received Message");
            if(request.action === "relist") {
                console.log("relist", request);
                this.props.dispatch(currentDesign({
                    id: request.data.design_slug,
                    meta:request.data.meta,
                }));
                this.setState({
                    value: {
                        key: request.data.design_slug,
                        name: request.data.design.title
                    },
                    selectedFile: request.data.file_slug
                })
            }
        });
}

Кто-нибудь знает, как я могу сказать фоновому сценарию ждать сообщения от компонента перед отправкой данных через

1 Ответ

0 голосов
/ 14 февраля 2019

Используйте долговременную связь между вашим контентом и фоновыми сценариями.

Представьте себе структуру папок, подобную этой:

├── content
├───── AwesomeComponent.js
├── background
├───── index.js
├── messenger.js
├── manifest.json

У вас будет скрипт, который отправляет / получает сообщения от обоихскрипты содержимого и фона.

messenger.js

import { relist } from 'background/index'

chrome.runtime.onConnect.addListener(function (port) {
  port.onMessage.addListener(function (request) {
    if (request.action === 'mounted') {
       // this message was sent by your AwesomeComponent
       // call relist to send data to content script
       relist()
    }

    if (request.action === 'relist') {
       // this message was sent by your background script
       // dispatch an action with request.data using your state management library
       // this will trigger an re-render in your React app and update its props
    }
  })
})

const context = typeof chrome.runtime.getBackgroundPage !== 'function' ? 'content' : 'background'

export function postMessage (request) {
  if (context === 'content') {
    const port = browser.runtime.connect()
    port.postMessage(request)
  } else {
    const port = browser.tabs.connect(request.tabId)
    port.postMessage(request)
  }
}

Включите модуль messenger.js в content/index.js.Это добавит слушателя chrome.runtime.onConnect.

content/AwesomeComponent.js

import React from 'react'
import { render } from 'react-dom'

import messenger from '../messenger'

class AwesomeComponent extends React.Component {
  // [...]

  componentDidUpdate(prevProps) {
    /* 
      Component was updated because a dispatch action was fired 
      through a message coming from the background script.
      Compare previous props and then use setState.
      You SHOULD compare them or it'll cause an infinite rendering loop!
      A comparison may be...
    */
    if (this.props.value.key !== prevProps.value.key) {
      this.setState({
        value: {
          key: props.design_slug,
          name: props.design.title
        },
        selectedFile: props.file_slug
      })
    }
  }

  componentDidMount () {
    // send a message to background
    messenger.postMessage({
       action: 'mounted'
    })
  }

  // [...]
}

Включите модуль messenger.js также в фоновый скрипт index.js.Это также добавит chrome.runtime.onConnect слушателя.

background/index.js

import messenger from '../messenger'

export function relist (data) {
  const data = ...
  chrome.tabs.create({ url: 'domain.com' }, () => {
    chrome.tabs.onUpdated.addListener(function reListener(tabId, info, tab) {
      if(tab.url === url && tab.status === 'complete') {
        console.log('Found tab');
        messenger.postMessage({
          tabId: tab.id,
          action: 'relist', 
          data: data
        })
        chrome.tabs.onUpdated.removeListener(reListener);
      }
   }
}

// other background stuff
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...