Skip to content

Instantly share code, notes, and snippets.

@evanlucas
Last active September 8, 2018 16:19
Show Gist options
  • Save evanlucas/dfb6dfc340e7b676b79496b80980da99 to your computer and use it in GitHub Desktop.
Save evanlucas/dfb6dfc340e7b676b79496b80980da99 to your computer and use it in GitHub Desktop.

Hack to log when a React component gets rendered

Set localStorage.debug = 'react'.

Make sure you install this before calling ReactDOM.render()

import React from 'react'
import monkeyPatch from './monkeyPatch'
monkeyPatch(React)
// ... include your normal ReactDOM.render()
import Debug from 'debug'
const debug = Debug('react')
const IGNORE_KEYS = new Set([
'length',
'name',
'prototype',
])
const IGNORE_HOCS = new Set([
'Connect',
'WithStyles',
'InjectIntl',
'pure',
'WithFormik',
'WithTheme',
])
export default function (React, options = {}) {
const hocs = options.hocs
? options.hocs
: IGNORE_HOCS
const originalCreateElement = React.createElement
React.createElement = (type, ...args) => {
if (!type || type.__isMonkeyPatched) {
return originalCreateElement(type, ...args)
}
const name = type.displayName || type.name
// Ignore our common HOCs
if (name) {
for (const hoc of hocs) {
if (name.startsWith(`${hoc}(`)) {
return originalCreateElement(type, ...args)
}
}
}
if (type.prototype && type.prototype.render) {
type.__isMonkeyPatched = true
const render = type.prototype.render
const name = type.displayName || type.name
type.prototype.render = function(...args) {
const props = this.props
const state = this.state
debug('render: %s', name, {props, state, args})
return render.call(this, ...args)
}
} else {
const name = type.displayName || type.name
if (name) {
type.__isMonkeyPatched = true
// Wrap in an object so Function#name can be inferred and be the same
// as the Component that we are wrapping.
const obj = {
[name]: function(...args) {
const props = args.length
? args[0]
: undefined
debug('render: %s', name, {props, args})
return type(...args)
}
}
obj[name].__isMonkeyPatched = true
for (const key of Object.getOwnPropertyNames(type)) {
if (IGNORE_KEYS.has(key)) continue
if (!obj[name][key]) {
obj[name][key] = type[key]
}
}
return originalCreateElement(obj[name], ...args)
}
}
return originalCreateElement(type, ...args)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment