你也想做掌控全局的 React 大师吗?

232 篇文章 0 订阅
219 篇文章 0 订阅
本文探讨如何通过React Lifecycle Hooks工具深入理解并监控React组件的生命周期。借助此工具,无需修改代码即可监听所有组件的生命周期事件,从而实现对React应用全局的洞察。文章介绍了原理,展示了DEMO,并展望了其在开发辅助工具和性能优化上的潜力。
摘要由CSDN通过智能技术生成

你也想做掌控全局的 React 大师吗?

 

你可能已经听说过大名鼎鼎的 why-did-you-update ,它能够发现程序中不必要的重新渲染:

其大致原理是将 React.Component.prototype.componentDidUpdate 覆盖为一个新的函数,在其中进行了每次渲染前后的 props 的深度比较,并将结果以友好直观的方式呈现给用户。但它有一个明显的缺陷——如果某一组件定义了 componentDidUpdate 方法, why-did-you-update 就失效了。

想要解决上述问题、并且更进一步地了解其他生命周期的触发情况,或者说,以上帝视角看到整个 React 应用的运行情况,该怎么做呢?

最直接的做法是,对每个组件修改其代码或使用 HoC 来达到目的。但有此类需求的项目体积往往已经具备一定规模,逐个修改代码的做法是不可接受的,想象一下在每个组件的代码都进行这样的修改会是多么繁琐的工作:

class App extends React.Component {
  // 手动添加该方法
  componentDidUpdate() {
    // ...
  }

  render() {
    return 'Hello, World!'
  }
}

// 或者使用 decorator
@addDidUpdate
class App extends React.Component {
  render() {
    return 'Hello, World!'
  }
}

 

那么有没有一款轻松易用,可以在一处监听项目中所有组件的工具呢?

有!

 

EnixCoda/ReactLifecycleHooks​github.com图标

react-lifecycle-hooks 可以帮助你可以对项目中所有组件的 React 生命周期事件进行监听,而完全不需要修改原有代码

// 假设这是项目中已有的一个组件, app.js
class App extends React.Component {
  render() {
    return 'Hello, World!'
  }
}

 

// 新建的监听专用文件,在必要时引入你的项目
import { activate, addMiddleware } from 'react-lifecycle-hooks'
import App from './path/to/app'

activate() // 这一行就都安排上了!

// 示例中间件,中间件在所有组件的所有生命周期触发时被调用,你可以通过如下过滤实现定向监听
function simplyLog(componentClass, componentInstance, lifecycleName, lifecycleArguments) {
  if (componentClass === App) {
    console.log('Going to execute', lifecycleName, 'of', componentClass.name, 'on', componentInstance)
  }
}

addMiddleware(simplyLog) // 从此开始,所有 App 组件上发生的事情会被 simplyLog 呈现于 console

一个 DEMO 明明白白​codesandbox.io图标

原理揭秘

是 JSX ,我加了 JSX 。

一切的秘密其实在 JSX ,让我们重新审视 JSX :

<Component prop={value}>{children}</Component>

JSX 是一种语法,在 React 下其对应的原生 JavaScript 表示约为

React.createElement(Component, { prop: value }, children)

React 的每一次渲染实际上是多次调用了 React.createElement 方法,生成对应的 JavaScript Object (VDOM)来表达视图。如果改写该方法,将记录每个传入的 Component ,就能追踪到所有被渲染的组件

核心代码摘要:

const { createElement } = react
function decorate(componentClass) { /* HoC */ }
react.createElement = function (type) {
  if (typeof type !== 'function') return createElement.apply(this, arguments)
  // type 是 组件类 或 无状态组件
  const decorated = decorate(type)
  return createElement.apply(this, [decorated].concat(Array.prototype.slice.call(arguments, 1)))
}

于是每次渲染出的 VDOM 中都是被 decorate 方法处理过的新组件,带有全套的生命周期方法。而且,由于新组件的生命周期是对原组件的巧妙包装,使用 react-lifecycle-hooks 不会对你的应用表现产生任何的影响,达到了无缝切入的效果。强烈建议你玩一下上方的在线 demo !

展望

react-lifecycle-hooks 的不是开箱即用可以直接为你提高生产力、解决实际问题的库,它只是提供了一个便于你掌握应用中 React 组件动态的入口,因此更像是为打造其他实用库而出现的基础库,比如在它之上可以开发出类似 React DevTools 的实用工具或优化 why-did-you-update!

// 简单改写 why-did-you-update
function whyDidYouUpdate(componentClass, componentInstance, lifecycleName, lifecycleArguments) {
  if (lifecycleName === 'componentDidUpdate') {
    const [ props, state ] = lifecycleArguments
    const prev = { props, state }
    const cur = { props: componentInstance.props, state: componentInstance.state }
    deepCompareAndPrint(prev, cur) // why-did-you-update 的深比较、输出方法
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值