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

如何在React的public文件夹脚本中调用Redux dispatch

解决方案

方案1:将Redux Store挂载到全局window对象

在src目录的store创建文件里,把store实例挂载到window上,让public目录的脚本能直接访问dispatch方法:

// src/store.js
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';

export const store = configureStore({
  reducer: rootReducer,
});

// 仅在开发环境或明确需要时挂载,避免生产环境暴露不必要的全局变量
if (process.env.NODE_ENV !== 'production') {
  window.store = store;
}

之后在public目录的脚本里直接调用:

// public/custom-script.js
// 假设要触发的action是updateData
window.store.dispatch({
  type: 'data/update',
  payload: { /* 从public脚本拿到的结果 */ }
});

注意:如果用Redux Toolkit的createSlice,建议提前导出action creators并挂载到window,或者直接指定type和payload。生产环境若需挂载,建议用更隐蔽的全局变量名避免冲突。

方案2:通过自定义事件(CustomEvent)实现跨脚本通信

这种方式无需暴露全局store,耦合度更低,更贴合React设计模式:

  1. 在public脚本中触发自定义事件,携带需要传递的数据:
// public/custom-script.js
// 假设已拿到要传给store的结果data
const updateEvent = new CustomEvent('storeUpdate', {
  detail: {
    payload: data,
    actionType: 'data/update'
  }
});
window.dispatchEvent(updateEvent);
  1. 在src的根组件(比如App.jsx)中监听事件,收到后调用dispatch:
// src/App.jsx
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { updateData } from './features/dataSlice'; // RTK的action creator

function App() {
  const dispatch = useDispatch();

  useEffect(() => {
    const handleStoreUpdate = (e) => {
      dispatch(updateData(e.detail.payload));
      // 也可以直接使用actionType:dispatch({ type: e.detail.actionType, payload: e.detail.payload });
    };

    window.addEventListener('storeUpdate', handleStoreUpdate);
    return () => window.removeEventListener('storeUpdate', handleStoreUpdate);
  }, [dispatch]);

  return (
    {/* 应用组件内容 */}
  );
}

export default App;

方案3:将public脚本逻辑迁移到src中

如果public脚本的功能可以在src内部实现,推荐这种方式,避免跨目录依赖问题:
比如加载第三方脚本并获取结果的场景,可以在src中动态加载脚本,回调中直接调用dispatch:

// src/components/ThirdPartyLoader.jsx
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { updateData } from './features/dataSlice';

function ThirdPartyLoader() {
  const dispatch = useDispatch();

  useEffect(() => {
    const script = document.createElement('script');
    script.src = '/custom-script.js'; // public目录下的脚本路径
    script.onload = () => {
      // 假设脚本加载后暴露全局方法getScriptResult
      window.getScriptResult((result) => {
        dispatch(updateData(result));
      });
    };
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
      delete window.getScriptResult; // 清理全局方法
    };
  }, [dispatch]);

  return null; // 无需渲染内容
}

export default ThirdPartyLoader;

在App组件中引入这个Loader组件即可。


内容的提问来源于stack exchange,提问作者Abenezer Bayeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:30:49