最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • useReducer —— 是的,数据驱动乃控熵大法

    正文概述 掘金(杜帅在掘金)   2021-05-30   816

    (但是,只在封闭系统生效!)

    早些时候,我对 hooks 下使用 useReducer 或者一众状态管理库是非常方案的,带上在结合项目仔细思考之下,发现了这一方案的优点,或许结合使用才是最优解

    对 useReducer 的产生误解的原因也很简单:

    1. 类型支持非常差(js/ts 没有很好的逆变类型支持,没有模式识别,对比 reasonml 下的 useReducer 可知)
    2. 无模式识别(同上)
    3. 无法在 useReducer 内部,利用第三方 hooks 生态(即封装状态逻辑视图的全功能第三方库)

    很简单一个例子,const {data,error} = useSwr(key,fetcher),这段代码将请求过程,全部转化为数据驱动的 data,error 状态,同时响应式支持了请求,延迟,屏幕聚焦,轮训,防抖等等功能

    开发过程中使用这样的 第三方 api 能够得到事半功倍的效果

    但是,如果你在这样的逻辑上,使用了 useReducer ,那么,这个叫做 useSwr 的 api,你无法再使用了,因为 reducer 内部代码(脱离了 react 调度

    这么说来,useReducer 在 hooks 环境下,就毫无作用可言了么?

    前文有提过,至少 react 所举的例子,并不能说明 useReducer 的意义:

    useReducer —— 是的,数据驱动乃控熵大法

    仅仅是因为 useCallback 有变化?就需要用 useReducer dispatch?

    const [todos,dispatch] = useReducer(todosReducer)
    return <TodosState value={todos}>
      <DeepTreeWithState/>
      <TodosDispatch.Provider value={dispatch}> 
        <DeepTreeWithDispatch />
      </TodosDispatch.Provider>
    </TodosState>
    

    甚至标准做法还应该做的这么丑陋?

    拜托,这个实在误人子弟了,控制 view 永远靠 useMemo,调度逻辑也是业务逻辑的一部分,哪能就这么回避掉的?

    直接返回未拆分的 jsx 本身的含义就是 —— 视图跟随所有 state,props,context 变化,逻辑即如此,反而 dispatch 虽不说不伦不类,也有点反直觉

    useReducer 该用么?现在告诉大家,某些情况下的确该用,但是不是 react 文档提到的这种情况(至少绝不会像他说的那么简单)

    什么情况下需要用到 useReducer ?

    封闭系统下的 控熵

    可以近似理解为,同一时刻,物体可能状态的数量,其中既包含状态的 数量,也包含状态的 可能性

    还记得前文总结的么?React 虽然在 hooks 这一次更新,做了很大的函数式改进,但是数据驱动原则始终未变

    毕竟直接由具象转化为抽象编程,跨度太大,前端又多是处在视图开发层次,状态或许比事件更加重要?

    然而函数式是不应该有太多状态,无共享状态甚至是无状态的,因为函数本身是对变化的抽象,用状态模拟概念编程,补足函数式顶层设计短板的做法,其实是有很大牺牲的(比如缺乏概念编程的自解释性,类型无协变,即类型无法自顶向下等)

    但是,现实是,前端必须两者兼得,必须尊重状态,因为前端开发本身就是中介,本身就是视图和一致性数据的中间件,状态绕不过去

    同样,即便是事件驱动(zone)著称的 angular,也没有像 cyclejs 那样无状态流一撸到底,cyclejs 的不温不火也能反过来证明这一点

    那么, 状态,以及背后代表的意义,就耐人寻味了

    因为

    状态就是熵

    下面这段表述我相信对 react 程序员来说,都是入门经典:

    useReducer —— 是的,数据驱动乃控熵大法

    没错!曼妥思糖和可乐!

    曼妥思碰到了可乐,双方产生剧烈反应,一方的不确定性和状态数量会直接灌入另一方中,这就是个剧烈的熵增反应

    useReducer —— 是的,数据驱动乃控熵大法

    左侧是你的应用中的状态,右侧是你收到的数据请求的状态,一旦两者想触碰,会发生什么?

    一边,是确定调度,确定结构的 react 应用,另一边,是不确定数据,不确定调度的异步

    将两者看做一个系统,怎么解决这个问题?

    没错!麦克斯韦妖!

    useReducer —— 是的,数据驱动乃控熵大法

    假设出现一个有选择能力的主体 —— 麦克斯韦妖,它选择性地将结果放入另一个结构(react 应用/store)中,就可以解决这个问题

    一边是确定性(低熵)的 state,通过这个 麦克斯韦妖(dispatch)选择 (reducer),很好地保证了 store 的低熵环境

    const [state,dispatch] = useReducer((state,action)=>{
      if(action.name === 'xxx'){
        // 麦克斯韦妖/reducer 正在进行选择
      }
      
      // 麦克斯韦妖/reducer 正在放入另一侧的 state 
      return {...state}
    },{})
    

    因此,前文提到的某个情景 —— 即应对非合成事件 的时候,callback 调用烧脑的问题(区分内外,区分调度源),useReducer 是个非常好的解决方案

    这个时候,dispatch 的不变性,才有了很好的使用场景:

    const ws = useRef()
    const [state,dispatch] = useReducer((state,action)=>{
      if(action.payload === 'init'){
        ws.current = new WebSocker('...')
      }
      if(action.payload === 'read'){
        ws.current.send('read')
      }
      // ...
    },{data:'',error:null})
    
    // 这样,应用本身的结构,可以很容易(effect,合成事件)与另一部分(非合成事件)进行交流
    
    useEffect(()=>{
      if(ready){
        dispatch('init')
      }
    },[ready])
    
    
    return <button onClick={()=>dispatch('init')}>init</button>
    

    这样的话,不确定性会比纯粹使用 useCallback 低得多(因为依赖很难得到处理,至少很烧脑)

    整个应用的熵得到了非常好的控制

    useReducer,系统对接的神器

    是的,当我们想要将一个封闭系统,与另一个系统对接,形成更大的封闭系统时,useReducer 就非常有用了,因为它控制住了不确定性

    将 dispatch 想象成麦克斯韦妖,你就能很轻松实现多个系统之间的隔离,并且有可预知的结果

    那么,除了异步以外,还有哪些地方可以用到呢?

    跨模块通讯!

    这部分以后可以继续分享,因为涉及一个笔者仍没有彻底弄懂的架构技术

    那全用 useReducer 可以么?

    本来是可以的,除非你不想要哪些全封装的第三方hooks api,以及不想要更简单明了的

    但是效率和质量是可以做权衡的,这部分看你怎么看,不过一旦你全使用 useReducer 进行开发,就是默认了,有 useReducer 处,就是个单独的模块

    也就是说,要么全用 useReducer,要么只用 useReducer 做模块通讯(其他调度系统的通讯也可以看做模块通讯)


    起源地下载网 » useReducer —— 是的,数据驱动乃控熵大法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元