React(5)React兄弟組件之間的通訊

前言

上一篇文章咱們經過一個ToDoList案例,系統的講解了React父子組件之間的通訊。本篇文章咱們依然經過一個實用的案例來爲你們講解React兄弟組件之間的通訊。javascript


1、兄弟組件之間的通訊原理

React項目中的兩個兄弟組件若要傳遞數據,則首先須要先將數據從一個兄弟組件傳遞給他們的公共父組件,而後再由這個公共父組件將數據傳遞給另外一個兄弟組件。數據傳遞的原理以下圖所示。
在這裏插入圖片描述
咱們經過一個案例來講明兄弟組件之間的通訊方式。該案例是一個顏色調色板,頁面中有三個滑竿,分別能夠調整紅色、綠色、藍色的取值範圍(0-255),在調整任意滑竿的過程當中,會自動顯示最終生成的顏色代碼,並將具體的顏色展現在一個div容器中。案例效果圖以下圖所示。
在這裏插入圖片描述前端

該案例爲了實現兄弟組件之間的數據傳遞,咱們將其劃分爲三個組件。java

  • 父組件:Color,用於調用兩個子組件,而且顯示最終的顏色代碼。
  • 子組件1:ColorBoard,用於顯示顏色拾取器中展現具體顏色的div容器。
  • 子組件2:ColorSelector,用於實現調整顏色的三個滑竿。

在這裏插入圖片描述

本案例中,三個滑竿的取值決定了最終的顏色代碼和顏色展現。因此初始化的數據位於組件ColorSelector中,當滑竿發生變化時,三個滑竿的取值都要傳遞給父組件,父組件將其轉換爲顏色代碼,再傳遞給子組件ColorBoard,子組件將其做用在用於展現顏色的div的背景顏色屬性上。組件之間數據的傳遞方向以下圖所示。
在這裏插入圖片描述小程序

2、三個組件的基本結構

咱們將組件劃分好以後,先按照效果圖將各個組件的元素位置書寫好。微信小程序

一、子組件ColorSelector的基本結構

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)} />

二、子組件ColorBoard的基本結構

class ColorBoard extends Component{
  render(){
    return (
      <Fragment>
        <div className="board"></div>
      </Fragment>
    )
  }
}

ColorBoard組件只具有一個div容器,最終會接收父組件Color傳遞過來的顏色代碼並經過style屬性改變背景顏色。app

三、父組件Color的基本結構

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的數據。函數

3、ColorSelector向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,也能夠用於在頁面上顯示顏色代碼。

4、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。兄弟組件之間地通訊順利完成。

5、項目完整代碼

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開發大力的進行普及。同時也願意與你們進行深刻的技術研討和商業合做。

相關文章
相關標籤/搜索