You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展中如何从Popup向主窗口传递React Context数据

问题解答

首先明确:默认情况下,Chrome Popup里的React Context无法直接被新窗口中的组件访问。因为Chrome的Popup和通过react-new-window创建的新窗口是完全独立的JavaScript执行环境,各自拥有独立的React组件树和Context实例,数据不会自动同步。

下面提供两种可行的实现方案,适配Chrome扩展的场景:


方案一:使用Chrome Storage API(推荐)

Chrome扩展的chrome.storage API可以在Popup、背景页、新窗口等扩展组件之间安全共享数据,同时支持持久化存储,是这类场景的最优解。

步骤1:修改Context,同步Chrome Storage

更新ScheduleContext.js,让Context的状态与Chrome Storage双向同步:

import React, { createContext, useContext, useState, useEffect } from 'react';

const ScheduleContext = createContext();

export const useScheduleContext = () => useContext(ScheduleContext);

export const ScheduleProvider = ({ children }) => {
  const [selectedRowData, setSelectedRowData] = useState(null);

  // 初始化时从Storage读取数据
  useEffect(() => {
    const loadInitialData = async () => {
      const storedData = await chrome.storage.local.get('selectedRowData');
      if (storedData.selectedRowData) {
        setSelectedRowData(storedData.selectedRowData);
      }
    };
    loadInitialData();

    // 监听Storage变化,自动同步到Context
    const handleStorageUpdate = (changes, area) => {
      if (area === 'local' && changes.selectedRowData?.newValue) {
        setSelectedRowData(changes.selectedRowData.newValue);
      }
    };
    chrome.storage.onChanged.addListener(handleStorageUpdate);

    return () => {
      chrome.storage.onChanged.removeListener(handleStorageUpdate);
    };
  }, []);

  // 封装状态更新方法,同时写入Storage
  const updateSelectedRow = async (data) => {
    setSelectedRowData(data);
    await chrome.storage.local.set({ selectedRowData: data });
  };

  return (
    <ScheduleContext.Provider value={{ selectedRowData, setSelectedRowData: updateSelectedRow }}>
      {children}
    </ScheduleContext.Provider>
  );
};

步骤2:配置扩展权限

在manifest.json中添加storage权限:

{
  "permissions": ["storage"]
}

步骤3:原有组件无需大幅修改

  • MainOrderList.js的handleRowClick逻辑保持不变,调用setSelectedRowData时会自动同步到Storage:
    const handleRowClick = (params) => {
      const rowData = params.row;
      setSelectedRowData(rowData);
    };
    
  • Schedules.js的逻辑也无需修改,Context会自动从Storage同步最新数据,useEffect会在数据更新时触发回调。

方案二:使用Window.postMessage(实时临时通信)

如果不需要持久化数据,仅需实时传递一次数据,可以用浏览器的postMessage API实现窗口间通信。

步骤1:Popup中保存新窗口引用并发送数据

假设Popup中负责打开新窗口的组件:

import React, { useState } from 'react';
import NewWindow from 'react-new-window';
import MainOrderList from './MainOrderList';
import { useScheduleContext } from 'src/context/ScheduleContext';

function PopupContainer() {
  const [newWindowInstance, setNewWindowInstance] = useState(null);
  const { setSelectedRowData } = useScheduleContext();

  const handleRowClick = (rowData) => {
    setSelectedRowData(rowData);
    // 向新窗口发送数据
    if (newWindowInstance?.window) {
      newWindowInstance.window.postMessage(
        { type: 'SELECTED_ROW', data: rowData },
        chrome.runtime.getURL('/') // 限制接收方为扩展内页面,提升安全性
      );
    }
  };

  return (
    <div>
      <MainOrderList onRowClick={handleRowClick} />
      <NewWindow onOpen={(window) => setNewWindowInstance({ window })}>
        <Schedules />
      </NewWindow>
    </div>
  );
}

步骤2:新窗口组件监听消息

更新Schedules.js,监听message事件并更新Context:

import React, { useEffect } from 'react';
import { useScheduleContext } from 'src/context/ScheduleContext';

export default function Schedules() {
  const { selectedRowData, setSelectedRowData } = useScheduleContext();

  useEffect(() => {
    const handleIncomingMessage = (event) => {
      // 验证消息来源,避免恶意数据
      if (event.origin !== chrome.runtime.getURL('/')) return;
      if (event.data.type === 'SELECTED_ROW') {
        setSelectedRowData(event.data.data);
      }
    };

    window.addEventListener('message', handleIncomingMessage);
    return () => window.removeEventListener('message', handleIncomingMessage);
  }, [setSelectedRowData]);

  useEffect(() => {
    if (selectedRowData) {
      console.log('Selected Row Data Updated:', selectedRowData);
      // 处理数据逻辑
    }
  }, [selectedRowData]);

  return <div>Schedule Component</div>;
}

内容的提问来源于stack exchange,提问作者Chandima Dilshan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:35:01