From the blog

Elegant React Component APIs with Functions as Children

react

We can develop some pretty elegant React Component APIs using functions as children in React Components. Take for example a Dropdown component. If we want it to be flexible by leaving the DOM structure up to the user, we would need some way to designate toggler elements of the Dropdown. One way is with the data-toggle attribute:

Open

However, this will require manually setting up event listeners on real DOM nodes, for example, the componentDidMount method on this component might look something like this:

componentDidMount() {
  const togglers = ReactDOM
    .findDOMNode(this)
    .querySelectorAll('[data-toggle]');
  Array.prototype.forEach.call(togglers, toggler => {
    toggler.addEventListener('click', this.toggle);
  });
},

A more elegant solution is to expose the component’s toggle method to its children by using a function as a child:

  {toggle =>

Open

 

}


This way, we’re using React’s event system instead of raw DOM events, and we wouldn’t need to implement componentDidMount at all.
When toggle is called, the opened CSS class will be toggled on the div element. In other words, the component would generate DOM that looks like this:

 

and when the toggle function is called, the opened class is added to the element:

 

The implementation of this Dropdown component looks like this:

const cx = require('classnames');
const enhanceWithClickOutside = require('react-click-outside');
const React = require('react');
const Dropdown = React.createClass({
  getInitialState() {
    return {
      opened: false,
    };
  },
  handleClick(e) {
    // Close dropdown when clicked on a menu item
    if (this.state.opened && e.target.tagName === 'A') {
      this.setState({ opened: false });
    }
  },
  handleClickOutside(e) {
    if (!this.state.opened) return;
    this.setState({ opened: false });
  },
  toggle() {
    this.setState({ opened: !this.state.opened });
  },
  render() {
    const child = this.props.children(this.toggle);
    return React.cloneElement(child, {
      className: cx(
        child.props.className,
        'dropdown',
        this.state.opened && 'opened'
      ),
      onClick: this.handleClick,
    });
  },
});
module.exports = enhanceWithClickOutside(Dropdown);

this.props.children is the function child of the Dropdown component, and it is called with the instance’s toggle method. This returns a React Element, the div, which we clone to add the dropdown and opened css classes.
A discussion of this pattern and other real world use cases can be found here.

Related articles

Cloud 3.0: The Rise of Big Compute

The next $100B+ opportunity in cloud computing and its first killer app: Deep Learning As we have entered into 2017, the enterprise software industry is at the inflection point for ubiquitous cloud adoption as part of the $4 trillion dollar […]

read more »

複数ジョブ実行時の時間と経費を節約する新機能:Persistent Clusters (永続クラスター)

RescaleのRahul Vergheseが、2017年1月19日に記載したBlog記事の翻訳です。 元記事はIntroducing Persistent Clusters: a New Feature to Save Time & Money with Multiple Jobsをご覧ください。 Rescaleは、最新のデプロイメントで新機能のPersistent Clusters (以下、「永続クラスター」:マニュアルで起動/削除可能なクラスター)をリリースしました。この機能を有効にすることで、複数のインスタンスを起動してクラスタを構築し、シャットダウン(訳注:Rescaleシステムではシャットダウン後インスタンスは削除されます)することなく、Rescaleワークフロー(Web UI)を使用して複数のジョブを順番に同じクラスターへ投入できます。以前は、各ジョブ毎にクラスターが稼働し、ジョブの完了後は自動的にシャットダウンされるため、複数の小さなジョブを実行すると遅延が発生する可能性がありました。この新しい機能により、繰り返し処理の高速化が可能になります。これは、テストや同じハードウェア構成を必要とする複数のジョブに特に便利です。 時間とお金を節約 一般に、各クラスターがスピンアップしてシャットダウンするまでには数分かかります。永続的クラスターを有効にしておくと、クラスターに追加する各ジョブの時間とコストを節約できます。 なぜ? 標準のクラスターは、ジョブが完了すると自動的にシャットダウンし、後続のジョブも同じように起動してシャットダウンするため、別々のクラスターとしてそれぞれ課金されます。(訳注:通常、たとえ10分の計算であっても1時間分の課金となるため、10分で完了する連続する2つのジョブを実行した場合、2時間分が課金されます)一方で、永続クラスターを使用すると、クラスターはすぐに次のジョブの実行に使用できるようになるため、ジョブ間で別のクラスターをシャットダウンして起動させる時間を無駄にしません。それによって、同様のジョブを多数立ち上げるユーザーにとって、時間とコストを大幅に節約することになります。(訳注:上記の例だとちょうど10分の計算を待ち時間なく2つ連続的に実施できることになり、1時間分の課金で収まることになります。)

read more »