简体   繁体   English

反应组件之间的通信

[英]React Communication Between Components

I am facing an architecture problem when trying this with React. 我在使用React尝试时遇到架构问题。 I want to toggle tabs in the most reusable way using React JS. 我想使用React JS以最可重用的方式切换选项卡。

So, ideally, I am looking for a way, in which on clicking on TabHeading, I deactivate the other TabHeadings in the TabHeader heading and also activate the corresponding TabPane (from this.props.target) in TabContent. 因此,理想情况下,我正在寻找一种方法,在单击TabHeading时,我停用TabHeader标题中的其他TabHeadings,还激活TabContent中相应的TabPane(来自this.props.target)。

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

I want to avoid the solution above. 我想避免上述解决方案。 I dont want to use classNames anywhere, or passing the parent component as a prop.Angular has $parent or somekind of variable to call functions on the parent right? 我不想在任何地方使用classNames或将父组件作为prop.Angular有$ parent或某种变量来调用父函数吗? Is there a similar way without explicitly passing the parent? 是否有类似的方法而不显式地通过父级? Is there a way to communicate with siblings? 有没有办法与兄弟姐妹交流? Please help. 请帮忙。

<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 File 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 JS小提琴

I found an answer without Flux. 我发现没有助焊剂的答案。 Please feel free to suggest ways to improve it. 请随时提出改进建议。

Tabs.js 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 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 JSFIDDLE- 链接

Are you open to using Flux? 您愿意使用Flux吗? An awful lot of tricky things with React alone become quite simple when you combine Flux with React. 当将Flux与React结合使用时,仅使用React的许多棘手事情就变得非常简单。

In this case, a store would keep track of the active tab. 在这种情况下, store将跟踪活动选项卡。 Clicking on an inactive tab would notify the store that a new tab should become active. 单击不活动的选项卡将通知商店新的选项卡应变为活动状态。 All of your individual tabs would subscribe to the store so that when the store changed the state of the active tab, all the siblings would be notified. 您所有的个人标签都将订阅该商店,以便当商店更改活动标签的状态时,将通知所有同级兄弟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM