自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ReactJS組件之間如何進行通信

開發(fā) 架構(gòu)
React的思想還是蠻獨特的,當然圍繞react的一系列自動化工具也是讓我感覺亞歷山大。今天總結(jié)一下react組件之間的通信,權(quán)當是自己的學(xué)習(xí)筆記:reactJs中數(shù)據(jù)流向的的特點是:單項數(shù)據(jù)流

最近在學(xué)習(xí)react.js,不得不說***次接觸組件化開發(fā)很神奇,當然也很不習(xí)慣。

react的思想還是蠻獨特的,當然圍繞react的一系列自動化工具也是讓我感覺亞歷山大

今天總結(jié)一下react組件之間的通信,權(quán)當是自己的學(xué)習(xí)筆記:

reactJs中數(shù)據(jù)流向的的特點是:單項數(shù)據(jù)流

react組件之間的組合不知道為什么給我一種數(shù)據(jù)結(jié)構(gòu)當中樹的感覺,數(shù)據(jù)就是從根節(jié)點(頂端或其他子樹的頂端)“流”下來,大概就是這個樣子:

 比如這是一個組件樹,數(shù)據(jù)就可以從main組件流到j(luò)umbotron組件、queationList組件、form組件,類似的queation組件的數(shù)據(jù)也可以流到下邊的question組件里邊。

但是很遺憾,這個從上到下的數(shù)據(jù)流動,只能解決很少的問題,還有一部分的數(shù)據(jù)流動就是類似從jumbotron組件到form組件的這樣的兄弟組件的流動形式,或者隔著幾個層級的數(shù)據(jù)流動,再或者子組件發(fā)生了數(shù)據(jù)的變化,想通知父組件,數(shù)據(jù)流向從子組件到父組件流,這些問題才是大多數(shù)的開發(fā)者需要面臨的問題。所以這篇筆記總結(jié)下基礎(chǔ)的組件通信:

數(shù)據(jù)從父組件到子組件

 最簡單的通信就是父子間的通信,比如上邊圖上的有個jsonObj從main流進了QueationList參考代碼:

  1. //這里模擬出幾條數(shù)據(jù) 
  2. var jsonObj=[ 
  3.     {name:"A",question:"從小被人打怎么辦?",TextArea:"習(xí)慣就好了",applaud:35,disagree:1}, 
  4.     {name:"B",question:"長的太帥被人砍怎么辦?",TextArea:"食屎啦你",applaud:35,disagree:10}, 
  5.     {name:"C",question:"因為太胖被人摸怎么辦?",TextArea:"享受就好了",applaud:35,disagree:45}, 
  6.     {name:"D",question:"被老師打不開心",TextArea:"用錢打臉",applaud:35,disagree:6}, 
  7.     {name:"E",question:"不愛洗澡怎么辦?",TextArea:"打一頓就好了",applaud:35,disagree:9} 
  8.  
  9. var QuestionList=React.createClass({ 
  10.     prepareToRender:function(list){ 
  11.         var array=[]; 
  12.         for(var i=0;i<list.length;i++){ 
  13.             array.push(<Question obj={list[i]}   key={i}/>); 
  14.         } 
  15.         return array; 
  16.     }, 
  17.     render:function(){ 
  18.         var array=this.prepareToRender(this.props.jsonObj); 
  19.         return <div>{array}</div>; 
  20.     } 
  21. }); 
  22. var Main = React.createClass({ 
  23.     //開始渲染 
  24.     render: function () { 
  25.         return ( 
  26.             <div> 
  27.                 <div className="container col-md-6 col-md-offset-3"
  28.                     <div className="container-fluid"
  29.                         <QuestionList jsonObj={jsonObj}  /> 
  30.                     </div> 
  31.             </div> 
  32.         ); 
  33.     } 
  34. }); 
  35. ReactDOM.render( 
  36.     <Main />, 
  37.     document.getElementById('container'
  38. );  

代碼寫的不怎么規(guī)范,但是數(shù)據(jù)的傳遞就是這樣的:

<QuestionList jsonObj={jsonObj} />

這樣就可以把父組件的數(shù)據(jù)帶到子組件里邊

數(shù)據(jù)從子組件到父組件

理論上來說數(shù)據(jù)只能是單向的,所以不借助插件數(shù)據(jù)還真不好從子組件到父組件,一種很簡單的手段是回調(diào)函數(shù):

在父組件當中寫個回調(diào)函數(shù),然后傳遞到子組件,什么時候子組件數(shù)據(jù)變化了,直接調(diào)這個回調(diào)函數(shù)就可以了。

 比如現(xiàn)在的jumbotron的按鈕被點擊了,我們想把被點擊這個事件發(fā)給它的父組件也就是main組件,那么我們可以這個做:

  1. var Jumbotron = React.createClass({ 
  2.     handleClick: function () { 
  3.         this.props.openTheWindow(false); 
  4.     }, 
  5.     render: function () { 
  6.         return ( 
  7.                 <div className="row"
  8.                     <div className="col-md-6  col-md-offset-3"
  9.                         <button type="button" className="btn btn-default btn-lg" onClick={this.handleClick}>開始體驗 
  10.                         </button> 
  11.                     </div> 
  12.                 </div> 
  13.             </div> 
  14.         ); 
  15.     } 
  16. }); 
  17.  
  18. var Main = React.createClass({ 
  19.     getInitialState: function () { 
  20.         return { 
  21.             openTheWindow: true 
  22.         }; 
  23.     }, 
  24.     //開始給子組件一個回調(diào)函數(shù),用來做子組件給父組件通信使用 
  25.     buttonResponse:function(windowSatus){ 
  26.         this.setState({openTheWindow : windowSatus}); 
  27.     }, 
  28.     //開始渲染 
  29.     render: function () { 
  30.         console.log(jsonObj) 
  31.         return ( 
  32.             <div> 
  33.                 <Jumbotron openTheWindow={this.buttonResponse}/> 
  34.             </div> 
  35.         ); 
  36.     } 
  37. }); 
  38. ReactDOM.render( 
  39.     <Main />, 
  40.     document.getElementById('container'
  41. );  

子組件通知父組件狀態(tài)變化就是這樣,就好像是兒子找爸爸要零花錢,零花錢以及給不給都是爸爸說了算的。

兄弟組件之間的通信

這個其實應(yīng)該是一個動態(tài)應(yīng)用中最常見的通信,比如jubotron組件的點擊按鈕,form組件的表單出現(xiàn):

這就是一個典型的兄弟之間的通信:

 兄弟節(jié)點其實可以就是子父通信&&父子通信的疊加

首先按鈕被點擊,子組件通知負組件這個事件,然后父組件把這個消息帶給另一個子組件

下邊是個點擊按鈕顯示表單的例子:

  1. /** 
  2.  * Created by niuGuangzhe on 2016/9/10. 
  3.  */ 
  4. var Jumbotron = React.createClass({ 
  5.     handleClick: function () { 
  6.         this.props.openTheWindow(false); 
  7.     }, 
  8.     render: function () { 
  9.         return ( 
  10.             <div className="jumbotron"
  11.                 <div className="row"
  12.                     <div className="col-md-6  col-md-offset-3"
  13.                         <button type="button" className="btn btn-default btn-lg" onClick={this.handleClick}>開始體驗 
  14.                         </button> 
  15.                     </div> 
  16.                 </div> 
  17.             </div> 
  18.         ); 
  19.     } 
  20. }); 
  21.  
  22. var Form = React.createClass({ 
  23.     getInitialState:function(){ 
  24.         return { 
  25.             inputTitle:"請輸入標題"
  26.             mainBody:"在此輸入正文" 
  27.         }; 
  28.     }, 
  29.     //點擊按鈕觸發(fā)事件:清除所有已經(jīng)輸入的文字 
  30.     cleanText:function(){ 
  31.         this.setState({ 
  32.             inputTitle:""
  33.             mainBody:""}); 
  34.     }, 
  35.     //表單監(jiān)視事件 
  36.     handleChange(name,e) { 
  37.         var newState = {}; 
  38.         console.log(name); 
  39.         newState[name] =event.target.value; 
  40.         this.setState(newState); 
  41.     }, 
  42.     render: function () { 
  43.         return ( 
  44.             <div style={{display:this.props.openTheWindow?"none":"block"}}> 
  45.                 <form role="form"
  46.                     <div className="form-group"
  47.                         <label htmlFor="title">標題</label> 
  48.                         <input type="text" className="form-control" id="title" name="inputTitle" value={this.state.inputTitle} onChange={this.handleChange.bind(this,"inputTitle")}/> 
  49.                     </div> 
  50.  
  51.                     <div className="form-group"
  52.                         <label htmlFor="textArea">正文</label> 
  53.                         <textarea className="form-control" rows="3" id="textArea" name="mainBody" value={this.state.mainBody} onChange={this.handleChange.bind(this,"mainBody")}></textarea> 
  54.                     </div> 
  55.                     <div className="row"
  56.  
  57.                         <input type="button" className="btn btn-default pull-right leaveMeAlone" value="取消"  onClick={this.cleanText}/> 
  58.                         <input type="submit" className="btn btn-primary pull-right leaveMeAlone" value="提交"/> 
  59.                     </div> 
  60.                 </form> 
  61.             </div> 
  62.         ) 
  63.     } 
  64. }) 
  65.  
  66.  
  67. var Main = React.createClass({ 
  68.     getInitialState: function () { 
  69.         return { 
  70.             openTheWindow: true 
  71.         }; 
  72.     }, 
  73.     //開始給子組件一個回調(diào)函數(shù),用來做子組件給父組件通信使用 
  74.     buttonResponse:function(windowSatus){ 
  75.         this.setState({openTheWindow : windowSatus}); 
  76.     }, 
  77.     //開始渲染 
  78.     render: function () { 
  79.         console.log(jsonObj) 
  80.         return ( 
  81.             <div> 
  82.                 <Jumbotron openTheWindow={this.buttonResponse}/> 
  83.                 <div className="container col-md-6 col-md-offset-3"
  84.                     <Form openTheWindow={this.state.openTheWindow}/> 
  85.                 </div> 
  86.             </div> 
  87.         ); 
  88.     } 
  89. }); 
  90. ReactDOM.render( 
  91.     <Main />, 
  92.     document.getElementById('container'
  93. );  

就是這樣,

其實上邊的代碼是我從之前的沒事干做的一個單頁面上拿過來改的,為了不出現(xiàn)代碼無法運行的問題,下邊貼出所有代碼:

  1. /** 
  2.  * Created by niuGuangzhe on 2016/9/10. 
  3.  */ 
  4. var Jumbotron = React.createClass({ 
  5.     handleClick: function () { 
  6.         this.props.openTheWindow(false); 
  7.     }, 
  8.     render: function () { 
  9.         return ( 
  10.             <div className="jumbotron"
  11.                 <div className="row"
  12.                     <div className="col-md-6  col-md-offset-3"
  13.                         <h2 className="colorChange">React+bootstrap簡單實例</h2> 
  14.                     </div> 
  15.                 </div> 
  16.                 <div className="row"
  17.                     <div className="col-md-6  col-md-offset-3"
  18.                         <p className="colorChange">上手體驗:***次嘗試組件化開發(fā)</p> 
  19.                     </div> 
  20.                 </div> 
  21.                 <div className="row"
  22.                     <div className="col-md-6  col-md-offset-3"
  23.                         <button type="button" className="btn btn-default btn-lg" onClick={this.handleClick}>開始體驗 
  24.                         </button> 
  25.                     </div> 
  26.                 </div> 
  27.             </div> 
  28.         ); 
  29.     } 
  30. }); 
  31.  
  32. var Form = React.createClass({ 
  33.     getInitialState:function(){ 
  34.         return { 
  35.             inputTitle:"請輸入標題"
  36.             mainBody:"在此輸入正文" 
  37.         }; 
  38.     }, 
  39.     //點擊按鈕觸發(fā)事件:清除所有已經(jīng)輸入的文字 
  40.     cleanText:function(){ 
  41.         this.setState({ 
  42.             inputTitle:""
  43.             mainBody:""}); 
  44.     }, 
  45.     //表單監(jiān)視事件 
  46.     handleChange(name,e) { 
  47.         var newState = {}; 
  48.         console.log(name); 
  49.         newState[name] =event.target.value; 
  50.         this.setState(newState); 
  51.     }, 
  52.     render: function () { 
  53.         return ( 
  54.             <div style={{display:this.props.openTheWindow?"none":"block"}}> 
  55.                 <form role="form"
  56.                     <div className="form-group"
  57.                         <label htmlFor="title">標題</label> 
  58.                         <input type="text" className="form-control" id="title" name="inputTitle" value={this.state.inputTitle} onChange={this.handleChange.bind(this,"inputTitle")}/> 
  59.                     </div> 
  60.  
  61.                     <div className="form-group"
  62.                         <label htmlFor="textArea">標題</label> 
  63.                         <textarea className="form-control" rows="3" id="textArea" name="mainBody" value={this.state.mainBody} onChange={this.handleChange.bind(this,"mainBody")}></textarea> 
  64.                     </div> 
  65.                     <div className="row"
  66.  
  67.                         <input type="button" className="btn btn-default pull-right leaveMeAlone" value="取消"  onClick={this.cleanText}/> 
  68.                         <input type="submit" className="btn btn-primary pull-right leaveMeAlone" value="提交"/> 
  69.                     </div> 
  70.                 </form> 
  71.             </div> 
  72.         ) 
  73.     }, 
  74.     //監(jiān)測從新渲染 
  75.     componentDidUpdate:function(){ 
  76.         console.log("子組件重新渲染;"); 
  77.     } 
  78. }) 
  79.  
  80. var Question = React.createClass({ 
  81.     getInitialState : function(){ 
  82.         return { 
  83.             click:true
  84.             disClick:true 
  85.         }; 
  86.     }, 
  87.     numberHandle:function(){ 
  88.         if(this.state.click===true){ 
  89.             //奇數(shù)次點擊,開始增加數(shù)據(jù) 
  90.             this.props.obj.applaud+=1; 
  91.             this.setState({click:false}); 
  92.         }else
  93.             //偶數(shù)次點擊,減去數(shù)據(jù) 
  94.             this.props.obj.applaud-=1; 
  95.             this.setState({click:true}); 
  96.         } 
  97.     }, 
  98.     decreateHandle:function(){ 
  99.         if(this.state.disClick===true){ 
  100.             //奇數(shù)次點擊,開始增加數(shù)據(jù) 
  101.             this.props.obj.applaud-=1; 
  102.             this.setState({disClick:false}); 
  103.         }else
  104.             //偶數(shù)次點擊,減去數(shù)據(jù) 
  105.             this.props.obj.applaud+=1; 
  106.             this.setState({disClick:true}); 
  107.         } 
  108.     }, 
  109.     render: function () { 
  110.         return ( 
  111.             <div className="row leaveMe"
  112.                 <div className="col-md-2"
  113.                     <div className="col-md-12"
  114.                         <button className="btn col-md-12 " onClick={this.numberHandle}>{this.props.obj.applaud-this.props.obj.disagree}<br/><span 
  115.                             className="glyphicon glyphicon-chevron-up"></span></button> 
  116.                     </div> 
  117.                     <span>&ensp;</span> 
  118.                     <div className="col-md-12"
  119.                         <button className="btn col-md-12" onClick={this.decreateHandle}><span 
  120.                             className="glyphicon glyphicon-chevron-down"></span> 
  121.                         </button> 
  122.                     </div> 
  123.                 </div> 
  124.                 <div className="col-md-10  bs-callout bs-callout-info"
  125.                     <h4>{this.props.obj.question}</h4> 
  126.                     <p>{this.props.obj.TextArea}</p> 
  127.                 </div> 
  128.             </div> 
  129.         ); 
  130.     } 
  131. }); 
  132.  
  133. var QuestionList=React.createClass({ 
  134.     prepareToRender:function(list){ 
  135.         var array=[]; 
  136.         for(var i=0;i<list.length;i++){ 
  137.             array.push(<Question obj={list[i]}   key={i}/>); 
  138.         } 
  139.         return array; 
  140.     }, 
  141.     render:function(){ 
  142.         var array=this.prepareToRender(this.props.jsonObj); 
  143.         return <div>{array}</div>; 
  144.     } 
  145. }); 
  146.  
  147.  
  148. //這里模擬出幾條數(shù)據(jù) 
  149. var jsonObj=[ 
  150.     {name:"A",question:"從小被人打怎么辦?",TextArea:"習(xí)慣就好了",applaud:35,disagree:1}, 
  151.     {name:"B",question:"長的太帥被人砍怎么辦?",TextArea:"食屎啦你",applaud:35,disagree:10}, 
  152.     {name:"C",question:"因為太胖被人摸奶怎么辦?",TextArea:"享受就好了",applaud:35,disagree:45}, 
  153.     {name:"D",question:"被老師打不開心",TextArea:"用錢打ta臉",applaud:35,disagree:6}, 
  154.     {name:"E",question:"不愛洗澡怎么辦?",TextArea:"打一頓就好了",applaud:35,disagree:9} 
  155.  
  156. var Main = React.createClass({ 
  157.     getInitialState: function () { 
  158.         return { 
  159.             openTheWindow: true 
  160.         }; 
  161.     }, 
  162.     //開始給子組件一個回調(diào)函數(shù),用來做子組件給父組件通信使用 
  163.     buttonResponse:function(windowSatus){ 
  164.         this.setState({openTheWindow : windowSatus}); 
  165.     }, 
  166.     //開始渲染 
  167.     render: function () { 
  168.         console.log(jsonObj) 
  169.         return ( 
  170.             <div> 
  171.                 <Jumbotron openTheWindow={this.buttonResponse}/> 
  172.                 <div className="container col-md-6 col-md-offset-3"
  173.                     <Form openTheWindow={this.state.openTheWindow}/> 
  174.                     <br/><br/> 
  175.                     <div className="container-fluid"
  176.                         <QuestionList jsonObj={jsonObj}  /> 
  177.                     </div> 
  178.                 </div> 
  179.             </div> 
  180.         ); 
  181.     }, 
  182. //    執(zhí)行hook函數(shù):重新渲染完成的時候調(diào)這個函數(shù) 
  183.     componentDidUpdate:function(){ 
  184.         console.log(this.state.openTheWindow); 
  185.     } 
  186. }); 
  187. ReactDOM.render( 
  188.     <Main />, 
  189.     document.getElementById('container'
  190. );  

***就是一個很重要的問題:就是多層級的據(jù)數(shù)據(jù)傳輸,如果還用這個方式來傳播的話,效率貌似是個大問題,解決辦法看大家的做法目前暫時還是flux之類的其他框架,等研究出來單獨寫篇文章吧

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2021-08-02 08:22:33

BlazorEventCallba通信

2014-09-19 10:46:36

LuaCC++

2010-03-18 19:39:44

Java Socket

2010-03-18 17:39:46

Java Socket

2010-06-02 14:16:18

SVN版本控制

2023-03-24 16:18:08

微服務(wù)架構(gòu)

2010-02-03 13:55:51

Python 代碼

2010-07-21 14:17:07

Linux telne

2010-09-13 10:45:04

2011-07-28 14:07:30

2023-09-03 23:49:35

2010-07-22 10:58:49

batch Telne

2013-01-28 10:11:24

敏捷設(shè)計敏捷開發(fā)

2017-07-28 11:31:59

iOS結(jié)構(gòu)優(yōu)化項目

2009-12-08 11:34:40

WCF Windows

2010-02-01 10:21:36

Python編碼轉(zhuǎn)換

2010-02-22 16:05:40

Python配置

2013-10-17 23:12:12

Windows 8.1Windows 8.1

2021-08-26 10:05:31

APP安全加密網(wǎng)絡(luò)攻擊

2024-07-08 08:38:37

Python游戲開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號