第九十二:前端即将或已经进入微件化时代

115 阅读7分钟

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

太多人把掌握一个工具软件的操作等同于掌握某个领域需要的专业能力。

如果你提供的数据图表能让人做出更有效的决策,那么我觉得它就是一个成功的图表,否则它仅仅是一个看起来很酷很美的东西,除了浪费大家的制作时间,并没有带来什么本质的改变。

前端即将或已经进入微件化时代

前段时间看到vue更新到了3.0版本,于是用3.0的vue起了一个项目,感受一下新的api。

最直观的感受是新的API createApp()和新的组合式API setup()。

以往我们创建新的项目一般直接使用new Vue(),创建子应用也需要自己去实现对应的加载逻辑,但是现在可以直接使用createApp()创建相应的子项目,同时它本身也带有自己的挂载和卸载方法。

以往我们直接在methods中写业务逻辑方法。现在直接可以在setup()中利用相应的钩子函数就可以实现想要的功能,尤其是业务逻辑比较复杂的情况下,可以相应的简化一些代码。

setup(props, context) {
    const router = useRouter()
    const {proxy} = getCurrentInstance()
    let form = reactive({
      username:"",
      password:''
    })
    let isReg = ref(false)
    // login
    const loginFn = async ()=> {
      console.log('form---',form)
      const {data,code} =  await login(form)
       const res =  await login(form)
      //  console.log('res---',res)
      if(code === 0){
        console.log('data----',data)
        router.push({
          name:'home'
        })
      }
    }
    // reg
    const goReg =()=>{
      proxy.isReg = !proxy.isReg
    }
    
    const regFn = async() => {
      const {data,code} = await regist(form)
      if(code === 0){
        console.log('data---regFn---',data)
      }
    }
    return {
      checkNick: false,
      formItemLayout,
      formTailLayout,
      form,
      isReg,
      goReg,
      loginFn,
      regFn
    };
  },

最近也看了react更新了v18的版本。

主包中增加了几个新的钩子函数:

  • useId

    用于在客户端和服务器上生成唯一的ID,同时避免不匹配。它主要用于与需要唯一ID的可访问性API集成的组件库。

  • startTransition 和 useTransition

    允许您将某些状态更新标记为不紧急。默认情况下,其他状态更新被视为紧急状态。React将允许紧急状态更新(例如,更新文本输入)中断非紧急状态更新(例如,呈现搜索结果列表)。

  • useDeferredValue

    允许您延迟重新渲染树的非紧急部分。它类似于去Bouncing,但与之相比有一些优势。没有固定的时间延迟,因此React将在第一次渲染反映在屏幕上后立即尝试延迟渲染。延迟渲染是可中断的,不会阻止用户输入。

  • useSyncExternalStore

    允许外部存储通过强制对存储进行同步更新来支持并发读取。在实现对外部数据源的订阅时,它消除了对useEffect的需要,建议任何与state external集成的库都使用它来做出反应。

  • useInsertionEffect

    允许JS库中的CSS解决在渲染中注入样式的性能问题。

同时react-dom分成了React DOM Client 和 React DOM Server。

React DOM Client

react-dom/client提供了createRoot 和 hydrateRoot方法。 createRoot 方法用来创建新的应用,并且提供了render和unmount方法。

import ReactDOM from "react-dom/client";
const root = ReactDOM.createRoot(
 document.getElementById("root")
);
root.render(
 <HashRouter>
  <App />
 </HashRouter>
)

React DOM Server是服务端渲染相关的内容,我们平时写的不多就不多说了。

其他的比较重要的变化:

  • 性能的改进。改变了反应批次更新的方式,以自动执行更多批处理。在极少数需要选择退出的情况下,将状态更新包装为flushSync。

  • 更严格的模式。未来,React将提供一个功能,允许组件在卸载之间保持状态。为了这个准备,React 18引入了一种新的仅限开发的严格检查模式。每当组件第一次装载时,React将自动卸载和重新装载每个组件,并在第二次装载时恢复以前的状态。如果这打破了我们的应用程序,考虑移除严格的模式,直到我们可以修复组件以恢复现有状态的弹性。

  • useEffect计时一致性。如果更新是在离散的用户输入事件(如单击或按键事件)期间触发的,则React始终同步刷新效果函数。以前,这种行为并不总是可预测或一致的。

  • 悬念树的一致性。(悬念*我个人理解为尚未加载到界面中的内容)如果组件在完全添加到树之前挂起,React将不会在不完整状态下将其添加到树中,也不会激发其效果。相反,React将完全丢弃新树,等待异步操作完成,然后重新尝试渲染。React将同时呈现重试尝试,而不会阻塞浏览器。

  • 悬念布局效果。当树重新挂起并恢复为回退时,React现在将清除布局效果,然后在边界内的内容再次显示时重新创建它们。这解决了一个问题,即当与未加载的组件一起使用时,组件库无法正确测量布局。

  • 新的JS环境要求。React 依赖于现代浏览器的功能,包括Promise、Symbol和Object。如果我们需要支持旧的浏览器和设备(如Internet Explorer),我们需要考虑别的实现方式。

其他的变化包括:

  • react组件现在可以返回undefined
  • 在未挂载的组件上调用setState不再发出警告。 之前,React在对未挂载组件调用setState时警告内存泄漏。此警告是为订阅添加的,但人们主要在设置状态良好的情况下遇到它,而解决方法会使代码变得更糟。
  • 不抑制控制台日志。当我们使用严格模式时,React会对每个组件渲染两次,以帮助我们发现意外的副作用。在React 17中,react抑制了两个渲染之一的控制台日志,以使日志更易于阅读。为了回应社区对这一令人困惑的反馈, react取消了压制。相反,如果安装了React DevTools,则第二个日志的渲染将以灰色显示,并且会有一个选项(默认情况下关闭)来完全抑制它们。
  • 提高内存使用率。React现在在卸载时清理更多的内部字段,使应用程序代码中可能存在的未修复内存泄漏的影响不那么严重。

和微件化的关系

说了这么多,都是在说react更新的内容。其实我们仔细思考一下,会发现vue 和 react 越来越像。同样的createApp 和 createRoot , 同样的useState 和reactive ,以及相关的useRouter 等钩子函数。

前几年比较火的前端微服务的概念,通常是基于路由,或着基于iframe,或者基于nginx配置进行实现。有了这些API,未来的前端微服务更多的会采用组件化的形式,通过div的id标识进行加载和卸载。

当然,现在就有一些微服务项目是通过div进行加载,但是这种实现形式比较麻烦,需要把子项目打包成静态资源,然后通过script的形式引入到主项目中。而组件化就显得更加方便,快捷,高效,同时也更加灵活。

抛开前端架构中的代码规范,工作流,持续集成,基于我们对业务细节非常熟练的前提,在不影响开发进度的前提下,将现有的复杂业务用微件化的概念进行重构,未来会是一个不错的选择。

最后

  • 公众号《JavaScript高级程序设计》
  • 公众号内回复”vue-router“ 或 ”router“即可收到 VueRouter源码分析的文档。
  • 回复”vuex“ 或 ”Vuex“即可收到 Vuex 源码分析的文档。

全文完,如果喜欢。

请点赞和"在看"吧,最好也加个"关注",或者分享到朋友圈。