web-dev-qa-db-ja.com

React.js:タブを作成するためのコンポーネントの作成

タブコンポーネントを作成しようとしています。 TabsSwitcherとTabsPanelは、DOMのどこでも使用できるように、別々のコンポーネントである必要があります。 TabsSwitcherの後にTabsPanelを続ける必要はありません。

それを機能させるには、これらのコンポーネントを何らかの方法で接続する必要があります。さらに、TabsSwitcherは、タブがクリックされたときにTabsPanelに通知できる必要があります。

/** @jsx React.DOM */

var TabsExample = React.createClass({
    render: function() {
        var tabs = [
            {title: 'first', content: 'Content 1'},
            {title: 'second', content: 'Content 2'}
        ];
        return <div>
            <TabsSwitcher items={tabs}/>
            <TabsContent items={tabs}/>
        </div>;
    }
});

var TabsSwitcher = React.createClass({
    render: function() {
        var items = this.props.items.map(function(item) {
            return <a onClick={this.onClick}>{item.title}</a>;
        }.bind(this));
        return <div>{items}</div>;
    },
    onClick: function(e) {
        // notify TabsContent about the click
    }
});

var TabsContent = React.createClass({
    render: function() {
        var items = this.props.items.map(function(item) {
            return <div>{item.content}</div>;
        });
        return <div>{items}</div>;
    }
});

React.renderComponent(
    <TabsExample/>,
    document.body
);

それを行うための最良の方法は何ですか?


解決策: http://jsfiddle.net/NV/5YRG9/

12
NVI

Reactのドキュメントでは、これについて「 コンポーネント間の通信 "」および「 複数のコンポーネント "」で詳しく説明しています。要点は、親が関数を小道具として子に渡し、子が必要なときにその関数をコールバックとして呼び出す必要があるということです。

var TabsExample = React.createClass({
    handleTabClick: function(item) {
        // Do something with item, maybe set it as active.
    },
    render: function() {
        var tabs = [
            {title: 'first', content: 'Content 1'},
            {title: 'second', content: 'Content 2'}
        ];
        return <div>
            <TabsSwitcher items={tabs} onTabClick={this.handleTabClick}/>
            <TabsContent items={tabs}/>
        </div>;
    }
});

var TabsSwitcher = React.createClass({
    render: function() {
        var items = this.props.items.map(function(item) {
            return <a onClick={this.onClick.bind(this, item)}>{item.title}</a>;
        }.bind(this));
        return <div>{items}</div>;
    },
    onClick: function(item) {
        this.props.onTabClick(item);
    }
});

TabsContentコンポーネントの場合、tabsTabsExample状態に移動して、Reactが変更されたときに自動的に再レン​​ダリングできるようにする必要があります。 TabsSwitcherTabsContentはrenderメソッドでタブに渡されるため、Reactはそれらがタブに依存していることを認識し、状態が変化すると再レンダリングします。

var TabsExample = React.createClass({
    getInitialState: function() {
        return {
            activeTabId: 1,
            tabs: [
                {title: 'first', content: 'Content 1', id: 1},
                {title: 'second', content: 'Content 2', id: 2}
            ]
        };
    };
    handleTabClick: function(item) {
        // Call `setState` so React knows about the updated tab item.
        this.setState({activeTabId: item.id});
    },
    render: function() {
        return (
            <div>
                <TabsSwitcher items={this.state.tabs}
                              activeItemId={this.state.activeTabId}
                              onTabClick={this.handleTabClick}/>
                <TabsContent items={this.state.tabs}
                             activeItemId={this.state.activeTabId}/>
            </div>
        );
    }
});
24
Ross Allen