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

关于在AEM项目中同时结合React Web组件与AEM组件使用Redux的可行性及实现咨询

关于在AEM项目中同时结合React Web组件与AEM组件使用Redux的可行性及实现咨询

嘿,看起来你已经在AEM项目里搭好了Redux的基础结构,还单独维护了一个React组件包,我来聊聊这种方案的可行性,以及具体怎么落地~

首先明确说:完全可行!AEM本身就支持整合React这类前端框架,你把状态管理(Redux)和UI组件拆分到不同包的思路其实很合理,能很好地实现逻辑与视图的解耦,也方便后续各自迭代维护。

下面是具体的实现步骤和注意事项:

一、让React组件包能访问到Redux Store

你的ui.frontend里已经配置好了Redux Store,但它和ui.frontend.react是两个独立的包,得先让React组件能拿到这个Store。这里推荐两种方式:

方式1:把Store暴露到全局(适合AEM前端打包场景)

在ui.frontend/src/app/site/utilities/store.js里,导出Store的同时把它挂载到window对象上,这样React组件初始化时就能直接获取:

import { configureStore } from '@reduxjs/toolkit';

const initialState = {
  count: 0
};

function countReducer(state = initialState, action) {
  const counter = state.count;
  if (action.type === 'INCREMENT') {
    return {
      ...state, 
      count: counter + 1
    };
  } else if (action.type === 'DECREMENT') {
    return {...state, count: counter - 1};
  } else {
    return state;
  }
}

const store = configureStore({
  reducer: {
    count: countReducer
  }
});

// 挂载到全局,供React组件访问
window.__REDUX_STORE__ = store;

export default store;

方式2:将ui.frontend作为依赖引入(适合npm包管理场景)

如果你用npm workspace或者yarn workspace管理项目,可以把ui.frontend设为ui.frontend.react的依赖,然后直接在React组件里import Store:

# 在ui.frontend.react目录下执行
npm install ../ui.frontend

然后在React代码里:

import store from 'ui.frontend/src/app/site/utilities/store';

二、在React组件中接入Redux

首先确保ui.frontend.react里安装了react-redux:

npm install react-redux

1. 用Provider包裹根组件

在React的入口文件(比如src/index.js)里,把全局的Store传入Provider,这样所有子组件都能共享Redux状态:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';

// 获取全局的Redux Store(如果是方式2就直接import)
const store = window.__REDUX_STORE__;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

2. 在自定义组件中使用Redux状态

以你的custom-button组件为例,用useSelector获取状态,useDispatch触发动作:

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

const CustomButton = () => {
  // 从Store中获取count状态
  const count = useSelector(state => state.count.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>当前计数: {count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>加1</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>减1</button>
    </div>
  );
};

export default CustomButton;

三、在AEM组件中正确加载资源

在AEM的ui.apps组件HTL文件里,要先加载包含Redux Store的前端资源,再加载React组件资源,确保React初始化时Store已经存在:

<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html">
  <!-- 先加载ui.frontend的clientlib(包含Redux Store) -->
  <sly data-sly-call="${clientlib.js @ categories='your-project.ui.frontend'}"/>
  <!-- 再加载ui.frontend.react的clientlib(包含React组件) -->
  <sly data-sly-call="${clientlib.js @ categories='your-project.ui.frontend.react'}"/>
</sly>

<!-- React组件挂载的容器 -->
<div id="react-root"></div>

四、一些优化和注意事项

  1. 简化Reducer写法:建议用Redux Toolkit的createSlice来替代手动写reducer,代码更简洁易维护,还能避免手动处理状态不可变的问题:

    import { createSlice } from '@reduxjs/toolkit';
    
    const initialState = {
      count: 0
    };
    
    const countSlice = createSlice({
      name: 'count',
      initialState,
      reducers: {
        increment: (state) => {
          state.count += 1;
        },
        decrement: (state) => {
          state.count -= 1;
        }
      }
    });
    
    // 导出action creators
    export const { increment, decrement } = countSlice.actions;
    export default countSlice.reducer;
    

    之后dispatch的时候就可以直接用dispatch(increment()),不用手动写action type啦。

  2. 状态同步到AEM组件:如果AEM原生组件也需要和Redux状态交互,直接在AEM的JS里调用全局Store的方法就行:

    // 获取当前状态
    const currentCount = window.__REDUX_STORE__.getState().count.count;
    // 触发动作
    window.__REDUX_STORE__.dispatch({ type: 'INCREMENT' });
    
  3. 避免重复打包依赖:在两个前端包的webpack配置里,把react、react-redux、@reduxjs/toolkit设为外部依赖,让它们共享全局实例,减小打包体积。

备注:内容来源于stack exchange,提问作者Stacy J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 07:52:58