React独立组件间通信联动
React是现在主流的高效的前端框架,其官方文档 http://reactjs.cn/react/docs/getting-started.html 在介绍组件间通信时只给出了父子组件间通信的方法,而没有给出独立组件间通信的解决方案。这里我介绍一种不错的实现方式——signals.
第一步,我们要建立两个简单的react组件——一个进度条和一个输入框。
组件——进度条:
var ProcessBar=React.createClass({ getInitialState:function(){ return { initValue:0, //初始值 endValue:0, //终值 totalValue:100 , //总值 }; }, render:function(){ var barStyle={ width:this.getPer(), }; return( <div className="progress"> <div className="progress-bar" style={barStyle}>{this.getPer()}</div> </div> ); } });
这个进度条的实现依赖于Bootstrp的进度条组件样式及特效,可以移步:http://v3.bootcss.com/components/#progress 查看。
组件——input框:
var Input=React.createClass({ getEndValue:function(){ var curValue=this.refs.endValue.value; if(curValue <= 0) curValue=0; if(curValue >=100) curValue=100; }, render:function(){ return ( <div> <input type="text" ref="endValue" placeholder="请输入值" onChange={this.getEndValue}/> </div> ); } });
两个独立的简单的组件已经完成了,下面就来看看如何使它们可以紧密联系,当input框中的值变化时,进度条可以实时变化。
在此,你可以借鉴另一篇博客了解解决独立组件间通信的几种策略——http://www.tuicool.com/articles/AzQzEbq。
这里,我主要介绍signals解决的方案。我们简单看下signals的github上的介绍:http://millermedeiros.github.io/js-signals/,看它给出的应用基本实例:
//custom object that dispatch a `started` signal var myObject = { started : new signals.Signal() }; function onStarted(param1, param2){ alert(param1 + param2); } myObject.started.dispatch('foo', 'bar'); //dispatch signal passing custom parameters
myObject.started.add(onStarted); //add listener
myObject.started.remove(onStarted); //remove a single listener
我们会发现,signals应用很简单,步骤为:
1:先创建一个signals.Signal的实例对象。
2:该对象通过dispatch()方法发布数据。
3:该实例对象提供add(function(data){})方法监听到数据,data默认为发布的数据。
4:如果需要,可以通过remove()关闭连接。
这里要提一下,就是因为发布和监听只能建立一个,所以我们的数据可以集中为一个数据对象,这样就可以大量传递数据了。
好,现在我们来应用到我们的组件中看看能不能解决我们的问题。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>processBar</title> <link rel="stylesheet" href="../../public/css/bootstrap-theme.min.css"/> <link rel="stylesheet" href="../../public/css/bootstrap.min.css"/> <script src="../../public/js/react-0.14.0.js"></script> <script src="../../public/js/react-dom-0.14.0.js"></script> <script src="../../public/js/jquery.js"></script> <script src="../../public/js/browser.min.js"></script> <script src="../../public/js/signals.js"></script> <script src="../../public/js/bootstrap.min.js"></script> <style> #exm{margin:20px auto;height:100px;border:1px solid #000;} .progress-bar{width:60%;} </style> </head> <body> <div id="exm"></div> <div id="exm2"></div> <script type="text/babel"> //设置数据广播 var broadData=new signals.Signal(); //全局数据广播对象 var datas={}; //总数据对象 var ProcessBar=React.createClass({ getInitialState:function(){ return { initValue:0, //初始值 endValue:0, //终值 totalValue:100 , //总值 }; }, getPer:function(){ var that=this; broadData.add(function(data){ //收听到数据 that.setState({ endValue:data.curValue, }); }); var per=(this.state.endValue-this.state.initValue)/this.state.totalValue *100+"%"; return per; }, render:function(){ var barStyle={ width:this.getPer(), }; return( <div className="progress"> <div className="progress-bar" style={barStyle}>{this.getPer()}</div> </div> ); } }); //输入框 var Input=React.createClass({ getEndValue:function(){ var curValue=this.refs.endValue.value; if(curValue <= 0) curValue=0; if(curValue >=100) curValue=100; datas.curValue=curValue; //将curValue放入总数居对象 broadData.dispatch(datas); //发布数据 }, render:function(){ return ( <div> <input type="text" ref="endValue" placeholder="请输入值" onChange={this.getEndValue}/> </div> ); } }); ReactDOM.render( //input框要先于进度条渲染 <Input/>, document.getElementById("exm2") ); ReactDOM.render( <ProcessBar/>, document.getElementById("exm") ); </script> </body> </html>
我们的代码效果如下:
我们的问题得到了解决!
所有代码可以在github上下载——https://github.com/Johnharvy/React-components-combo。
如果以上内容对您有所帮助,请帮我点个推荐吧,传播整理知识,有利你我。