组件之间的反应通信

时间:2015-07-01 15:40:27

标签: javascript reactjs

使用React尝试使用时,我遇到了一个架构问题。我想使用React JS以最可重用的方式切换选项卡。

所以,理想情况下,我正在寻找一种方法,在单击TabHeading时,我会停用TabHeader标题中的其他TabHeadings,并在TabContent中激活相应的TabPane(来自this.props.target)。

$(".tab-pane").hide();
$(React.findDOMNode(this.props.target)).show();

我想避免上面的解决方案。我不想在任何地方使用classNames,或者将父组件作为prop.Angular传递父元素或somekind变量来调用父元素上的函数?有没有明确传递父亲的类似方式?有没有办法与兄弟姐妹沟通?请帮忙。

<Tabs>
    <TabHeader>
        <TabHeading active="active" target={self.refs.pane1}>
            Heading 1
        </TabHeading>
        <TabHeading target={self.refs.pane2}>
            Heading 2
        </TabHeading>
    </TabHeader>
    <TabContent>
        <TabPane active="active" ref="pane1">
            Pane 1
        </TabPane>
            <TabPane ref="pane2">
               Pane 2
            </TabPane>
    </TabContent>
</Tabs>

JS档案

var React = require("react");
var $ = require("jquery");

var TabHeader = React.createClass({
    render: function(){
        return(
            <div className="tab-header">
                {this.props.children}
            </div>
        );
    }
});

var TabHeading = React.createClass({
    componentDidMount : function(){

    },
    handleClick : function(e){
         //something to set siblings to inactive
         //this.props.active="active";
         // this.props.target.props.active = "active";

    },
    render: function(){
        return(
            <div className="tab-heading" onClick={this.handleClick} >
                {this.props.children}
            </div>
        );
    }
});


var TabContent = React.createClass({
    render: function(){
        return(
            <div className="tab-content">
                {this.props.children}
            </div>
        );
    }
});


var TabPane = React.createClass({
    componentDidMount:function(){
        console.log(this.props.children);
    },
    render: function(){
        return(
            <div className="tab-pane">
                {this.props.children}
            </div>
        );
    }
});


var Tabs = React.createClass({
    componentDidMount:function(){

    },
    render: function(){
        return(
            <div className="tabs">
            {this.props.children}
            </div>
        );
    }
});
Tabs.TabHeader = TabHeader;
Tabs.TabHeading = TabHeading;
Tabs.TabContent = TabContent;
Tabs.TabPane = TabPane;

module.exports = Tabs;

JSfiddle

2 个答案:

答案 0 :(得分:1)

我找到了没有Flux的答案。请随时提出改进方法。

<强> Tabs.js

var React = require("react");
var $ = require("jquery");


var TabHeading = React.createClass({

render : function(){
        var view  ;

        return (
                <div onClick={this.props.handleClick} className={this.props.active? "active tab-heading" : "tab-heading"}>
                        {this.props.children}
                    </div>      
            );
    }   
 });



var TabPane = React.createClass({
render : function(){

        return (
            <div className={this.props.active? "active tab-pane" : "tab-pane"}>
                    {this.props.children}
                </div>
            );
    }   
});

var Tabs = React.createClass({

handleClick:function(){
    this.props.active = arguments[0];
    this.forceUpdate();
},
render : function(){
    var self = this;
    console.log("rendering");
    var tabHeadings = this.props.tabHeadings.map(function(item,index){
         active = (index==self.props.active);
         return <TabHeading key={index} handleClick={self.handleClick.bind(self,index)} index={index} active={active}>{item}</TabHeading>
    });
    var tabPanes= self.props.tabPanes.map(function(item,index){
         active = (index==self.props.active);
         return <TabPane key={index} active={active}>{item}</TabPane>

    });

    return (
                <div className="tab">
                    <div className="tab-header">
                            {tabHeadings}
                    </div>
                    <div className="tab-content">
                            {tabPanes}
                    </div>
                </div>
        );
}
});

module.exports = Tabs;

<强> File.js

render:function(){

    var self = this;

    var tabHeading1 = (
            <p> Heading 1 </p>
        );
    var tabHeading2 = (
            <p> Heading 2 </p>
        );
    var tabPane1 = (
            <p> Pane 1 </p>
        );
    var tabPane2 = (
            <p> Pane 2 </p>
        );
    var tabHeadings = [tabHeading1,tabHeading2];
    var tabPanes = [tabPane1,tabPane2];

    return (<div>
            <div className="container">
                <Tabs tabHeadings={tabHeadings} tabPanes={tabPanes} active="0"/>
            </div>
            </div>
        );
}

JSFIDDLE - link

答案 1 :(得分:0)

您是否愿意使用Flux?当你将Flux和React结合起来时,单独使用React的很多棘手的事情变得非常简单。

在这种情况下,store会跟踪活动标签。单击非活动选项卡将通知商店新选项卡应变为活动状态。所有单独的选项卡都会订阅商店,以便当商店更改活动选项卡的状态时,将通知所有兄弟姐妹。