当前位置: 首页 > 科技观察

ReactJS组件之间如何通信

时间:2023-03-12 12:39:25 科技观察

最近在学习react.js,不得不说第一次接触组件开发是很神奇的,当然也很不习惯。react的思想还是比较独特的。当然围绕react的一系列自动化工具也让我觉得Alexander今天总结了react组件之间的通信。应该是自己的学习笔记:reactJs中数据流的特点是:数据单一不知道为什么streamreact组件的组合给我一种数据结构中树状的感觉。数据从根节点(树顶或其他子树的树顶)往下“流”,大概是这样的:比如这是一个组件树,数据可以从主组件流到jumbotron组件,queationList组件,和表单组件,类似queation组件的数据也可以流向下面的question组件。但遗憾的是,这种自上而下的数据流只能解决很少的问题,部分数据流是从jumbotron组件到form组件的兄弟组件的流形式,或者是隔了好几层的child的数据流组件,或者说子组件的数据变化,要通知父组件,数据流向是从子组件流向父组件,这些问题是大部分开发者需要面对的问题。所以这篇笔记总结了基本的组件通信:父组件到子组件最简单的数据通信就是父子之间的通信。比如上图中有一个jsonObj从main流入QueationList。参考代码://这里模拟了几条数据varjsonObj=[{name:"A",question:"小时候被打了怎么办?",TextArea:"习惯了",鼓掌:35,disagree:1},{name:"B",question:"我长得太帅被人砍怎么办?",TextArea:"你吃屎",applaud:35,disagree:10},{name:"C",question:"如果有人因为你太胖而碰你怎么办?",TextArea:"Enjoyit",applaud:35,disagree:45},{name:"D",question:"被老师打了不开心",TextArea:"拿钱打脸",applaud:35,disagree:6},{name:"E",question:"不打脸怎么办喜欢洗澡吗?”,TextArea:“小睡一下”,鼓掌:35,不同意:9}]varQuestionList=React.createClass({prepareToRender:function(list){vararray=[];for(vari=0;i);}returnarray;},render:function(){vararray=this.prepareToRender(this.props.jsonObj);return

{array}
;}});varMain=React.createClass({//开始渲染render:fu功能(){返回(
);}});ReactDOM.render(
,document.getElementById('container'));代码不是很规范,但是数据传递是这样的:子组件到父组件的数据理论上只能是单向的,所以子组件到父组件不借助插件数据是不行的。一个很简单的方法就是回调函数:在父组件中写一个回调函数,然后传递给子组件。当子组件的数据发生变化时,直接调用回调函数即可比如现在点击了jumbotron的按钮,我们想把clicked事件发送给它的父组件,也就是主组件,那么我们可以这样做:varJumbotron=React.createClass({handleClick:function(){this.props.openTheWindow(false);},render:function(){return(开始体验
);}});varMain=React.createClass({getInitialState:function(){return{openTheWindow:true};},//开始给子组件一个回调函数,作为子组件使用buttonResponse与父组件通信:function(windowSatus){this.setState({openTheWindow:windowSatus});},//开始渲染render:function(){console.log(jsonObj)return(
);}});ReactDOM.render(
,document.getElementById('container'));子组件是这样通知父组件状态变化的,就好像儿子找爸爸要零用钱,给不给零用钱爸爸说了算。兄弟组件之间的通信实际上应该是动态应用程序中最常见的通信。比如jubotron组件的按钮被点击时出现form组件的表单:这是一个典型的兄弟之间的通信:兄弟节点实际上可以是父子通信&&父子通信覆盖首先按钮被点击,子组件将这个事件通知否定组件,然后父组件将这个消息发送给另一个子组件下面是一个点击按钮显示表单的例子:/***CreatedbyniuGuangzheon2016/9/10。*/varJumbotron=React.createClass({handleClick:function(){this.props.openTheWindow(false);},render:function(){return(开始体验);}});varForm=React.createClass({getInitialState:function(){return{inputTitle:"请输入标题",mainBody:"在此输入文字"};},//点击按钮触发事件:清除所有已经输入的文本cleanText:function(){this.setState({inputTitle:"",mainBody:""});},//表单监听事件handleChange(name,e){varnewState={};console.log(name);newState[name]=event.target.value;this.setState(newState);},render:function(){return(标题文字)}})varMain=React.createClass({getInitialState:function(){return{openTheWindow:true};},//开始给子组件一个回调函数,用于与父组件使用buttonResponse进行通信:function(windowSatus){this.setState({openTheWindow:windowSatus});},//开始渲染render:function(){console.log(jsonObj)return(
);}});ReactDOM.render(
,document.getElementById('container'));就是这样,其实上面的代码是从我之前无所事事的单个页面中取出来的。为了避免代码无法运行的问题,我把所有代码贴在下面:/***CreatedbyniuGuangzheon2016/9/10.*/varJumbotron=React.createClass({handleClick:function(){this.props.openTheWindow(false);},render:function(){return(React+bootstrap简单示例上手体验:组件化开发初体验

开始体验);}});varForm=React.createClass({getInitialState:function(){return{inputTitle:"请输入标题",mainBody:"这里输入text"};},//点击按钮触发事件:清除所有输入的文本cleanText:function(){this.setState({inputTitle:"",mainBody:""});},//表单监听eventhandleChange(name,e){varnewState={};console.log(name);newState[name]=event.target.value;this.setState(newState);},render:function(){return(标题title)},//监听重新渲染componentDidUpdate:function(){console.log("子组件重新渲染;");}})varQuestion=React.createClass({getInitialState:function(){return{click:true,disClick:true};},numberHandle:function(){if(this.state.click===true){//奇数次点击,开始增加数据this.props.obj.applaud+=1;this.setState({click:false});}else{//偶数点击,减去数据this.props.obj.applaud-=1;this.setState({click:true});}},decreateHandle:function(){if(this.state.disClick===true){//奇数次点击,开始增加数据this.props.obj.applaud-=1;this.setState({disClick:false});}else{//偶数次点击,减去数据this.props.obj.applaud+=1;this.setState({disClick:true});}},render:function(){return({this.props.obj.applaud-this.props.obj.disagree}
?

{this.props.obj.question}

{this.props.obj.TextArea}

);}});varQuestionList=React.createClass({prepareToRender:function(list){vararray=[];for(vari=0;i);}returnarray;},render:function(){vararray=this.prepareToRender(this.props.jsonObj);return
{array}
;}});//这里模拟出几条数据varjsonObj=[{name:"A",q问题:“小时候被打了怎么办?”,TextArea:“习惯就好”,鼓掌:35,不同意:1},{name:“B”,问题:“What太帅被人砍我怎么办?",TextArea:"你吃屎",applaud:35,disagree:10},{name:"C",question:"别人摸我的怎么办胸部是因为我太胖了?”,TextArea:“好好享受吧”,鼓掌:35,不同意:45},{name:“D”,question:“被老师气坏了”,TextArea:“扇她耳光有钱的脸",applaud:35,disagree:6},{name:"E",question:"不爱洗澡怎么办?",TextArea:"小睡一会儿就好",applaud:35,disagree:9}]varMain=React.createClass({getInitialState:function(){return{openTheWindow:true};},//开始给子组件一个回调函数,用来和子组件通信父组件使用buttonResponse:function(windowSatus){this.setState({openTheWindow:windowSatus});},//开始渲染render:function(){console.log(jsonObj)return(


);},//执行钩子函数:重新渲染完成时调用此函数componentDidUpdate:function(){console.log(this.state.openTheWindow);}});ReactDOM.render(
,document.getElementById('container'));***是一个很重要的问题:多级数据传输,如果还是用这种方式传播的话,效率好像是个大问题,解决办法还是看大家的做法,目前暂时使用flux等其他框架,研究一下再单独写一篇吧。