博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你也想做掌控全局的 React 大师吗?
阅读量:4250 次
发布时间:2019-05-26

本文共 2690 字,大约阅读时间需要 8 分钟。

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

 

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

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

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

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

class App extends React.Component {  // 手动添加该方法  componentDidUpdate() {    // ...  }  render() {    return 'Hello, World!'  }}// 或者使用 decorator@addDidUpdateclass App extends React.Component {  render() {    return 'Hello, World!'  }}

 

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

有!

 

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

// 假设这是项目中已有的一个组件, app.jsclass 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

原理揭秘

是 JSX ,我加了 JSX 。

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

{children}

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

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

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

核心代码摘要:

const { createElement } = reactfunction 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-updatefunction 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 的深比较、输出方法  }}

 

转载地址:http://hjkei.baihongyu.com/

你可能感兴趣的文章
tensorflow+tensorflow-serving+docker+grpc模型上线部署(不需bazel编译,有代码)
查看>>
甘特图——Excel搞定
查看>>
J2EE是什么(二)
查看>>
J2EE是什么(一)
查看>>
Java学习——何为JNDI
查看>>
Java学习——传说中的13个规范
查看>>
前端页面——揭开级联查询的面纱
查看>>
前端页面——AJAX是个什么样的传输机
查看>>
前端页面——Cookie与Session有什么区别
查看>>
DRP问题系列——The Network Adapter could not establish the connection
查看>>
Java学习——Servlet是什么
查看>>
项目总结——传说中的反射竟然是这个样子
查看>>
前端页面——js如何让数据传输更灵活
查看>>
VS发布网站后的文件夹为空
查看>>
ITOO4.0项目总结--成长
查看>>
DRP问题系列——Unhandled event loop exception
查看>>
总结过去——从不着边到步入正轨
查看>>
java学习——XML文件导入
查看>>
java学习——架构的设计是项目的核心
查看>>
Java学习——String变量中的双胞胎
查看>>