【问题标题】:React Communication Between ComponentsReact 组件之间的通信
【发布时间】:2015-09-18 21:07:06
【问题描述】:

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

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

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

我想避免上述解决方案。我不想在任何地方使用类名,或者将父组件作为道具传递。Angular 有 $parent 或某种变量来调用父组件上的函数,对吗?有没有类似的方法没有明确传递父母?有没有办法和兄弟姐妹交流?请帮忙。

<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

【问题讨论】:

  • 如果您将代码放入 jsbin/jsfiddle/codepen 会有所帮助,这样我们就可以破解它以获得答案:)
  • stackoverflow.com/q/22461129/368697 可能会回答您的问题。这也是关于使用 React 组件维护选项卡状态。
  • @ssorallen:很酷的答案。但是,我需要添加自定义 HTML,如果我采用这种方法会很困难。

标签: javascript reactjs


【解决方案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;

文件.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

【讨论】:

    【解决方案2】:

    您愿意使用 Flux 吗?当您将 Flux 与 React 结合使用时,仅使用 React 的许多棘手的事情就会变得非常简单。

    在这种情况下,store 将跟踪活动选项卡。单击非活动选项卡将通知商店新选项卡应该变为活动状态。您的所有个人选项卡都将订阅商店,因此当商店更改活动选项卡的状态时,所有兄弟姐妹都会收到通知。

    【讨论】:

    • 是的,也对它开放。正在努力。如果你能想出一段代码,那就太棒了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-02-02
    • 2014-12-21
    • 2017-04-07
    • 2017-09-12
    • 2019-11-17
    • 2015-11-05
    • 2019-05-30
    • 2016-06-09
    相关资源
    最近更新 更多