V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
yazoox
V2EX  ›  JavaScript

有没有比较好的成熟的实践方案,可以用于的 npm package 内部的 UI 交互。

  •  
  •   yazoox · 86 天前 · 796 次点击
    这是一个创建于 86 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不知道标题有没有讲清楚需求,再详细讲述一下。

    现在需要开发一个 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? 以前完全没有使用过这个方案,不清楚成本有多高,会不会有什么技术坑...

    第 1 条附言  ·  85 天前

    比如,一个标准的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,会不会冲突了......

    7 条回复    2021-06-29 12:00:39 +08:00
    xiaoming1992
        1
    xiaoming1992   86 天前 via Android
    包内的 redux 可以放到 externals 中
    yazoox
        2
    yazoox   85 天前
    @xiaoming1992 不好意思,没有看懂。你这里的 externals 是指?
    LiuJiang
        3
    LiuJiang   85 天前
    看看 Ant Design 源码
    duan602728596
        4
    duan602728596   85 天前
    组件不要用 redux,你这么做,如果多个相同组件存在,却公用同一个状态,会出问题的。
    内部可以考虑使用 useReducer 和 useContext 配合使用。
    baxtergu
        5
    baxtergu   85 天前
    看了上面的问题,我理解你的担心是如果存在多 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 方式来解决你的问题,根据你上面的描述这种方式完全可以满足你的需求。
    xiaoming1992
        6
    xiaoming1992   85 天前 via Android
    @yazoox 如果你的包是 webpack 打包的,那么你可以将 react & redux 放在 webpack 配置的 externals 中,这样就会使用包外的 react / redux 了,就会显得包没那么“重”了。如果不是 webpack 就当我没说 2333

    组件内复杂的状态管理,我没什么太好的办法
    yazoox
        7
    yazoox   85 天前
    @duan602728596
    @baxtergu
    好的,我去看看,学习一下 useReducer & useContext 组合使用。
    thx.
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1102 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:42 · PVG 06:42 · LAX 15:42 · JFK 18:42
    ♥ Do have faith in what you're doing.