Component life cycle

As you might have noticed, React has an opinionated view on a component's API. But it also has a very strong opinion on its life cycle, allowing us developers to add hooks to create custom behavior and perform cleanup tasks as we develop our components.

This is one of React's greatest triumphs because it is through this standardization that we can create bigger and better components by composition; through that, we can use not only our components, but other people's components.

To demonstrate one use case, we are going to implement a very simple behavior: on page load, we want the new investment form stock symbol input to be focused so that a user can start typing right away.

But, before we can start writing the test, there is just one thing that we will need to do. As mentioned earlier, TestUtils.renderIntoDocument doesn't actually render anything in the document, but instead on a detached node. So, if we use it to render our component, we won't be able to make the assertion regarding the input's focus.

So, yet again, we have to use the setFixtures method to actually render the React component in the document, as follows:

/**
  Uses jasmine-jquery fixtures to actually render in the document.
  React.TestUtils.renderIntoDocument renders in a detached node.

  This was required to test the focus behavior.
 */
function actuallyRender (component) {
  setFixtures('<div id="application-container"></div>'),
  var container = document.getElementById('application-container'),
  return React.render(component, container);
}

describe("NewInvestment", function() {
  var TestUtils = React.addons.TestUtils;
  var component, stockSymbol;

  function findNodeWithClass (className) {
    return TestUtils.findRenderedDOMComponentWithClass(component, className).getDOMNode();
  }

  beforeEach(function() {
    component = actuallyRender(<NewInvestment onCreate={onCreateSpy}/>);
    stockSymbol = findNodeWithClass('new-investment-stock-symbol'),
  });

  it("should have its stock symbol input on focus", function() {
    expect(stockSymbol).toBeFocused();
  });
});

With this small change completed, and the spec written, we can get back to the implementation.

React gives a few hooks that we can implement custom code in our component during its life cycle; they are as follows:

  • componentWillMount
  • componentDidMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate
  • componentWillUnmount

To implement our custom behavior, we are going to use the componentDidMount hook that is called only once, right after the component was rendered and attached into a DOM element.

So, what we want to do is somehow inside this hook, get access to the input DOM element and trigger its focus. We already know how to get a DOM node; it is through the getDOMNode API. But, how do we get the input's React element?

React's other feature for this problem is called ref. It is basically a way to give names to a component's children to allow later access.

Since we want the stock symbol input, we need to add a ref attribute to it, as follows:

<input type="text" ref="stockSymbol" className="new-investment-stock-symbol" valueLink={this.linkState('stockSymbol')} maxLength="4" />

Then, at the componentDidMount hook, we can get the input by its ref name and then its DOM element and trigger the focus, as follows:

var NewInvestment = React.createClass({
  // ...
  
componentDidMount: function () {
    this.refs.stockSymbol.getDOMNode().focus();
  }
,
  // ...
});

The other hooks are setup in the same way, by simply defining them on the class definition object as properties. But each is called on different occasions, and has different rules. The official documentation is a great resource on their definition and possible use-cases which can be found at http://facebook.github.io/react/docs/component-specs.html#lifecycle-methods.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset