Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js: modify render() method for all components?

For debugging reasons I'd like to add following line into general render() method, so it would be executed in all components.

console.log('render' + this.constructor.displayName, this.state);
like image 736
Ladislav M Avatar asked May 25 '15 20:05

Ladislav M


People also ask

Can a render method return multiple elements?

render() should return single element. You can split it up and have multiple components which implement some dedicated logic which is better and used to be a good practice in React.

Does React re-render all components?

React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.

Why does a component requires a render () method?

When the component file is called it calls the render() method by default because that component needs to display the HTML markup or we can say JSX syntax.

What does a render () method in Reactjs return?

Purpose of render(): React renders HTML to the web page by using a function called render(). The purpose of the function is to display the specified HTML code inside the specified HTML element. In the render() method, we can read props and state and return our JSX code to the root component of our app.


1 Answers

I assume you want to do this without changing any of the existing code. I played around with this and found a way to do so if you're using something like webpack or browserify to build your application and you're using React v0.13.

It's important to note that this uses private methods, reaching into React's internals, and could break at any time. That said, it might be useful for your debugging purposes.

[Update to the Update]

If you use Babel, I highly recommend checking out the React Transform plugin. This will let you do all sorts of nifty stuff to React, including wrapping (or overwriting!) render methods.

[Update]

I've found a way to do this without hacking into React.addons.Perf; the key was the module name of ReactCompositeComponent and the function name of _renderValidatedComponent—just wrap that method to inject your custom behavior.

Note you'll need to place this code before you require("react").

var ReactCompositeComponent = require("react/lib/ReactCompositeComponent");
var oldRenderValidatedComponent = ReactCompositeComponent.Mixin._renderValidatedComponent;
ReactCompositeComponent.Mixin._renderValidatedComponent = function() {
  var name = this.getName();
  if (name && !name.match(/^ReactDOM/)) {
    console.log("render: ", this.getName(), {props: this._instance.props, state: this._instance.state});
  }
  return oldRenderValidatedComponent.apply(this, arguments);
}

You'll then end up with a very similar result as the old answer, below. I've added better logging of props and state, and filter out any of the built in ReactDOM* components.

Example


[Old Answer]

I've overridden the default measure function of the performance tools, which React calls through its codebase to measure performance when using React.addons.Perf. By doing so, we're able to get the information that the default measurement strategy would normally get. Note that this breaks the normal behavior React.addons.Perf.

Add this code to the entry-point of your application (after you require React):

var ReactInjection = require("react/lib/ReactInjection");
var ReactDefaultPerf = require("react/lib/ReactDefaultPerf");

ReactDefaultPerf.start();
ReactInjection.Perf.injectMeasure(function measure(moduleName, fnName, fn) {
  return function() {
    if (moduleName === 'ReactCompositeComponent' && fnName === '_renderValidatedComponent') {
      var name = this.getName();
      if (name) {
        console.log("render: ", name);
      }
    }

    return fn.apply(this, arguments);
  }
});

And you'll get the following in your console logs:

Console

ReactElements with no names (that is, components that make up regular HTML elements like span and div) are not shown. One notable set of exceptions is button and other input elements, as React provides composite components that wrap those to help manage state. They show up as ReactDOMButton and ReactDOMInput.

like image 100
Michelle Tilley Avatar answered Sep 30 '22 05:09

Michelle Tilley