上一篇文章咱們經過一個ToDoList案例,系統的講解了React父子組件之間的通訊。本篇文章咱們依然經過一個實用的案例來爲你們講解React兄弟組件之間的通訊。javascript
React項目中的兩個兄弟組件若要傳遞數據,則首先須要先將數據從一個兄弟組件傳遞給他們的公共父組件,而後再由這個公共父組件將數據傳遞給另外一個兄弟組件。數據傳遞的原理以下圖所示。
咱們經過一個案例來講明兄弟組件之間的通訊方式。該案例是一個顏色調色板,頁面中有三個滑竿,分別能夠調整紅色、綠色、藍色的取值範圍(0-255),在調整任意滑竿的過程當中,會自動顯示最終生成的顏色代碼,並將具體的顏色展現在一個div容器中。案例效果圖以下圖所示。
前端
該案例爲了實現兄弟組件之間的數據傳遞,咱們將其劃分爲三個組件。java
本案例中,三個滑竿的取值決定了最終的顏色代碼和顏色展現。因此初始化的數據位於組件ColorSelector中,當滑竿發生變化時,三個滑竿的取值都要傳遞給父組件,父組件將其轉換爲顏色代碼,再傳遞給子組件ColorBoard,子組件將其做用在用於展現顏色的div的背景顏色屬性上。組件之間數據的傳遞方向以下圖所示。
小程序
咱們將組件劃分好以後,先按照效果圖將各個組件的元素位置書寫好。微信小程序
class ColorSelector extends Component{ constructor(props){ super(props); this.state={ colors:[255,255,255] } } render(){ return ( <Fragment> { this.state.colors.map((item,index)=>{ return <input type="range" key={index} min={0} max={255} /> }) } </Fragment> ) } }
爲了可以獲取三個滑竿的最終數值,咱們在state區設置了一個名爲colors的數據,該數據是一個數組,共有三個數組元素,分別用來表示三個滑竿的最終數值。數組
滑竿也屬於表單元數,和上一篇文章中使用文本框的方法是同樣的。爲滑竿添加value屬性設置默認值,綁定onChange事件獲取用戶交互數據,在onChange事件中使用event.target.value獲得最終的結果。因此上述代碼中滑竿的部分最終變爲下列格式。微信
return <input type="range" key={index} min={0} max={255} value={item} onChange={()=>this.colorChange(event,index)} />
class ColorBoard extends Component{ render(){ return ( <Fragment> <div className="board"></div> </Fragment> ) } }
ColorBoard組件只具有一個div容器,最終會接收父組件Color傳遞過來的顏色代碼並經過style屬性改變背景顏色。app
class Color extends Component{ constructor(props) { super(props); this.state={ color:'#FFFFFF' } } render(){ return ( <Fragment> <ColorBoard /> <div>顏色代碼:{this.state.color}</div> <ColorSelector /> </Fragment> ) } }
父組件爲了接受子組件ColorSelector傳遞過來的數組並最終轉換爲顏色代碼,在其state區設置了一個名爲color的數據。函數
因爲滑竿在子組件ColorSelector中,因此咱們要先進行子組件向父組件的數據傳遞。這時父組件要在調用子組件時設置一個自定義事件,並在子組件中滑竿的onChange事件中調用這個自定義事件。this
父組件在調用ColorSelector子組件時設置的自定義事件以下所示。
<ColorSelector onSelect={this.colorSelect.bind(this)}/>
子組件ColorSelector的滑竿onChange事件以下所示。
colorChange(event,index){ const {onSelect}=this.props; let colors=[...this.state.colors]; colors[index]=parseInt(event.target.value); this.setState({ colors }); onSelect(this.state.colors); }
在該段代碼中,首先把記錄三個滑竿數據的數組colors解構爲colors變量,並經過event.target.value獲取索引值爲index的滑竿的最終數據,經過索引值改變變量colors的數組元素取值,並最終將變量colors再複製給state數據colors。最後調用父組件的onSelect事件,並將state區的colors數組傳給父組件的onSelect事件。
父組件中自定義事件onSelect觸發時執行的函數以下所示。
colorSelect(colors){ let temp='#' + colors.map(item=>{ return item>15?item.toString(16):'0'+item.toString(16); }).join(''); this.setState({ color:temp.toUpperCase() }) }
父組件的onSelect事件接收到子組件ColorSelector傳遞的數組,將其遍歷並將每一個數組元素轉換爲16進制,最終變爲表示顏色色代碼的字符串。最後將這個字符串所有轉換爲大寫,並賦值給父組件state區的color數據,這樣既能夠用於傳遞給子組件ColorBoard,也能夠用於在頁面上顯示顏色代碼。
接下來,父組件應該將接收到的顏色代碼color傳遞給另外一個子組件ColorBoard了,以用來在div容器中顯示背景顏色。這時,父組件在調用子組件ColorBoard時,應該爲其設置一個自定義屬性,用來傳遞顏色代碼。代碼以下所示。
<ColorBoard color={this.state.color}/>
子組件ColorBoard應該獲取父組件傳遞的顏色代碼並經過style屬性改變div容器的背景顏色。代碼以下所示。
const {color}=this.props; return ( <Fragment> <div className="board" style={{backgroundColor:color}}></div> </Fragment> )
至此,三個滑竿的數據完整的從子組件ColorSelector中傳遞給了另外一個子組件ColorBoard,在父組件中轉的過程當中,將ColorSelector傳來的數組轉換爲顏色代碼傳給ColorBoard。兄弟組件之間地通訊順利完成。
const {Component,Fragment} = React; /*子組件ColorBoard*/ class ColorBoard extends Component{ render(){ const {color}=this.props; return ( <Fragment> <div className="board" style={{backgroundColor:color}}></div> </Fragment> ) } } /*子組件ColorSelector*/ class ColorSelector extends Component{ constructor(props){ super(props); this.state={ colors:[255,255,255] } } colorChange(event,index){ const {onSelect}=this.props; let colors=[...this.state.colors]; colors[index]=parseInt(event.target.value); this.setState({ colors }); onSelect(this.state.colors); } render(){ return ( <Fragment> { this.state.colors.map((item,index)=>{ return <input type="range" key={index} min={0} max={255} value={item} onChange={()=>this.colorChange(event,index)} /> }) } </Fragment> ) } } /*父組件Color*/ class Color extends Component{ constructor(props) { super(props); this.state={ color:'#FFFFFF' } } colorSelect(colors){ let temp='#' + colors.map(item=>{ return item>15?item.toString(16):'0'+item.toString(16); }).join(''); this.setState({ color:temp.toUpperCase() }) } render(){ return ( <Fragment> <ColorBoard color={this.state.color}/> <div>顏色代碼:{this.state.color}</div> <ColorSelector onSelect={this.colorSelect.bind(this)}/> </Fragment> ) } } ReactDOM.render( <Color></Color>, document.getElementById('app') );
本文是React系列教程的第五篇文章,主要爲你們講解了React兄弟組件之間的通訊方式。本質是依然是父子組件之間的通訊。明天會爲你們系統的講解React中受控表單元素的使用方法。
小海前端,具備18年Web項目開發和先後臺培訓經驗,在前端領域著有較爲系統的培訓教材,對Vue.js、微信小程序開發、uniApp、React等全棧開發領域都有較爲深的造詣。入住Segmentfault,但願可以更多的結識Web開發領域的同仁,將Web開發大力的進行普及。同時也願意與你們進行深刻的技術研討和商業合做。