不知道标题有没有讲清楚需求,再详细讲述一下。
现在需要开发一个 npm package,这个包里面有一个大的 UI 组件,大家可以理解为一个 panel 。panel 上半部分是一个 tree 结构,下半部分是一个 sub-panel 。选中 tree 里面的一个结点,会显示该结点的“内容”到下方的 sub-panel 里面去。或者右键某结点,弹出一个菜单,点击菜单项,能够执行一些操作,或者弹出一个 dialog (该 dialog 也属于这个 package ),等等。
大家可能觉得很奇怪,一般我们都会把 UI 的 components 做成纯组件,然后放到一个 package 里面。这样,该 ui components 就可以被许多项目引用了。但是,我们这个需求,这个 package 里面包含的 ui 组件,不是纯组件,是有 logic,即业务逻辑在里面了。我们复用的是这个业务模块。
我能够想到的就是使用 react-redux,因为,弹出 /隐藏一个的 dialog,弹出 /隐藏菜单或者点击一个结点,显示 /隐藏 sub-panel,通过 redux 的集中管理 dispatch actions,比较容易实现。尤其是,一些异步操作,我们都是使用 redux-saga 。但是在一个 package 内使用 redux & redux-saga,感觉有点儿“重”。而且,我们的项目本身也是基于 react,并且大量使用了 redux & redux-saga 。我不知道我们项目的 application 在使用这个 package 后,app 的 redux store 会不会和 package 内部 ui 的 redux store 冲突。到时候 dispatch actions 会不会混乱,等等。
所以,特意来请教一下大家。对于这类需求,有没有比较好的成熟的实践方案。
谢谢!
p.s. 项目是 react, ts, redux 的技术栈
p.s.2 使用 Mobx? 以前完全没有使用过这个方案,不清楚成本有多高,会不会有什么技术坑...
比如,一个标准的react-redux用法
const rootElement = document.getElementById('root')
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
)
但此时,如果App这个组件,里面使用了一个sub-app组件,该组件是import from一个3rd party npm package. 该组件里面,也是类似这样的
<Provider store={store}>
<component />
</Provider>
这样的话,主app的store和component的store,会不会冲突了......
1
xiaoming1992 2021-06-29 02:15:37 +08:00 via Android
包内的 redux 可以放到 externals 中
|
2
yazoox OP @xiaoming1992 不好意思,没有看懂。你这里的 externals 是指?
|
3
LiuJiang 2021-06-29 08:57:52 +08:00
看看 Ant Design 源码
|
4
duan602728596 2021-06-29 09:28:35 +08:00
组件不要用 redux,你这么做,如果多个相同组件存在,却公用同一个状态,会出问题的。
内部可以考虑使用 useReducer 和 useContext 配合使用。 |
5
baxtergu 2021-06-29 10:07:35 +08:00
看了上面的问题,我理解你的担心是如果存在多 redux Store 实例的情况下,由 Context-Provider 向下传入的 store value 会不会被互相覆盖,其实 react-redux 提供了多实例的使用方式,使用起来会增加你应用开发的复杂度,具体链接: https://react-redux.js.org/using-react-redux/accessing-store#multiple-stores 。(需要在 Provider 中和组件的 connect 中手动指定 Context 实例方式手工指定 store 的来源)
但是不推荐你这么做,因为会让使用你组件的开发者带来不小的心智负担。 - - - 假设你的组件逻辑非常复杂(如:富文本编辑器、拖拽组件等)一定要选一种数据流方案将逻辑外置的话,推荐你用 mobx (开启严格模式),但是使用时候一定要注意 mobx 获取的所有对象实例都是 mutable 的,有时候需要手动去处理引用相等问题导致组件不更新,最新版的 mobx-react 也是对 hooks api 很友好的,非常方便。 - - - 最推荐的做法还是使用 Context + useReducer 来自定义 hooks 方式来解决你的问题,根据你上面的描述这种方式完全可以满足你的需求。 |
6
xiaoming1992 2021-06-29 10:26:24 +08:00 via Android
@yazoox 如果你的包是 webpack 打包的,那么你可以将 react & redux 放在 webpack 配置的 externals 中,这样就会使用包外的 react / redux 了,就会显得包没那么“重”了。如果不是 webpack 就当我没说 2333
组件内复杂的状态管理,我没什么太好的办法 |
7
yazoox OP |