React 組件通信域庇,父子傳值、跨組件傳值丽焊、兄弟組件傳值

一较剃、父?jìng)髯?/h3>

父組件:

class App extends Component {
  render() {
    return (
      <div>
        {/* 類組件 */}
        <Child name="李四" age={26} hobbies={['睡覺']} />
        {/* 類組件默認(rèn)值 */}
        <Child />
        {/* 函數(shù)組件 */}
        <Child2 />
      </div>
    )
  }
}

類子組件:

class Child extends Component {
  render() {
    const { name, age, hobbies } = this.props;
    return (
      <div>
        <h3>{`姓名:${name},年齡:${age}`}</h3>
        <h3>愛好:</h3>
        <ul>
          {
            hobbies.map(item => {
              return <li key={item}>{item}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

函數(shù)子組件:

function Child2(props) {
  const { name, age, hobbies } = props;
  return (
    <div>
      <h3>{`姓名:${name}技健,年齡:${age}`}</h3>
      <h3>愛好:</h3>
      <ul>
        {
          hobbies.map(item => {
            return <li key={item}>{item}</li>
          })
        }
      </ul>
    </div>
  )
}

類子組件中設(shè)置默認(rèn)值及類型檢查:

class Child extends Component {
  // 類型檢查
  static propTypes = {
    // isRequired 必傳
    name: PropTypes.string.isRequired,
    age: PropTypes.number,
    hobbies: PropTypes.array
  }
  // 設(shè)置默認(rèn)值
  static defaultProps = {
    name: "小明",
    age: 18,
    hobbies: ['吃飯', '睡覺', '打豆豆']
  }
  render() {
    const { name, age, hobbies } = this.props;
    return (
      <div>
        <h3>{`姓名:${name},年齡:${age}`}</h3>
        <h3>愛好:</h3>
        <ul>
          {
            hobbies.map(item => {
              return <li key={item}>{item}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

函數(shù)組件和類組件通用設(shè)置默認(rèn)值及類型檢查:

// 類型檢查
Child2.propTypes = {
  // isRequired 必傳
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  hobbies: PropTypes.array
}
// 設(shè)置默認(rèn)值
Child2.defaultProps = {
  name: "小明",
  age: 18,
  hobbies: ['吃飯', '睡覺', '打豆豆']
}

二惰拱、子傳父

父組件:

class App extends Component {
  constructor() {
    super();
    this.state = {
      data: []
    }
  }
  render() {
    return (
      <div>
        <Child getData={this.handleGetData} />
        <h2>列表:</h2>
        <ul>
          {
            this.state.data.map(item => {
              return <li key={item}>{item}</li>
            })
          }
        </ul>
      </div>
    )
  }
  // 定義箭頭函數(shù)接收子組件傳過來(lái)的值
  handleGetData = (data) => {
    this.setState({
      data
    })
  }
}

子組件:

class Child extends Component {
  constructor() {
    super();
    this.state = {
      // 子組件初始值
      data: ['a', 'b', 'c']
    }
  }
  render() {
    const { getData } = this.props;
    return (
      // 將子組件的值傳遞到父組件
      <button onClick={e => getData(this.state.data)}>獲取數(shù)據(jù)</button>
    )
  }
}

三雌贱、跨組件通信(context)

Context 提供了一個(gè)無(wú)需為每層組件手動(dòng)添加 props,就能在組件樹間進(jìn)行數(shù)據(jù)傳遞的方法偿短。

父組件:

// 創(chuàng)建 Context 并設(shè)置默認(rèn)值
const listContext = React.createContext([111, 222, 333])

// 父組件
class App extends Component {
  constructor() {
    super();
    this.state = {
      list: ['aaa', 'bbb', 'ccc']
    }
  }
  render() {
    return (
      <div>
        <div>我是父組件</div>
        {/* 調(diào)用 Provider 組件發(fā)送數(shù)據(jù) */}
        <listContext.Provider value={this.state}>
          <Child />
        </listContext.Provider>
      </div>
    )
  }
}

子組件:

class Child extends Component {
  render() {
    return (
      <div>
        <div>我是子組件</div>
        <GrandSon />
      </div>
    )
  }
}

孫子組件(類):

class GrandSon extends Component {
  // 接收 Context
  static contextType = listContext;
  constructor() {
    super();
    this.state = {};
  }
  render() {
    return (
      <div>
        <div>我是孫子組件</div>
        <ul>
          {
            this.context.list.map(item => {
              return <li key={item}>{item}</li>
            })
          }
        </ul>
      </div>
    )
  }
}
  • 通過類組件里定義 static contextType 接收父組件傳遞過來(lái)的 Context 值欣孤。**
// 接收父組件傳遞過來(lái)的 Context 值
static contextType = listContext;
  • 通過組件名調(diào)用 ContextType 接收父組件傳遞過來(lái)的 Context 值。
// 通過類名接收父組件傳遞過來(lái)的 Context 值
GrandSon.contextType = listContext;

孫子組件(函數(shù)):

function GrandSon() {
  return (
    <div>
      <div>我是孫子組件</div>
      <ul>
        {/* 通過 Consumer 組件接收數(shù)據(jù) */}
        <listContext.Consumer>
          {
            value => {
              return value.list.map(item => {
                return <li key={item}>{item}</li>
              })
            }
          }
        </listContext.Consumer>
      </ul>
    </div>
  )
}

四昔逗、兄弟組件通信(events)

import React, { PureComponent } from 'react';
import { EventEmitter } from 'events';

// 定義事件總線
const eventsBus = new EventEmitter();

// 子組件1
class Child1 extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      message: ''
    }
  }
  // 監(jiān)聽事件總線獲取的值
  componentDidMount() {
    eventsBus.addListener('sayHello', this.handleSayHelloListener.bind(this))
  }
  handleSayHelloListener(message) {
    this.setState({
      message
    })
  }
  // 銷毀監(jiān)聽事件
  componentWillUnmount() {
    eventsBus.removeListener('sayHello', this.handleSayHelloListener);
  }
  render() {
    return (
      <div>
        子組件1
        <h2>子組件2的消息:</h2>
        {this.state.message}
      </div>
    )
  }
}

// 子組件2
class Child2 extends PureComponent {
  render() {
    return (
      <div>
        子組件2
        <button onClick={() => this.sendMsg()}>發(fā)送消息</button>
      </div>
    )
  }
  // 從子組件 2 發(fā)送消息至子組件 1
  sendMsg() {
    eventsBus.emit('sayHello', '你好降传,我是子組件2', 666)
  }
}

class App extends PureComponent {
  render() {
    return (
      <div>
        <Child1 />
        <Child2 />
      </div>
    );
  }
}
export default App;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市勾怒,隨后出現(xiàn)的幾起案子婆排,更是在濱河造成了極大的恐慌,老刑警劉巖笔链,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件段只,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鉴扫,警方通過查閱死者的電腦和手機(jī)赞枕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坪创,“玉大人炕婶,你說我怎么就攤上這事±吃ぃ” “怎么了柠掂?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)锁施。 經(jīng)常有香客問我陪踩,道長(zhǎng)杖们,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任肩狂,我火速辦了婚禮摘完,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘傻谁。我一直安慰自己孝治,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布审磁。 她就那樣靜靜地躺著谈飒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪态蒂。 梳的紋絲不亂的頭發(fā)上杭措,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音钾恢,去河邊找鬼手素。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瘩蚪,可吹牛的內(nèi)容都是我干的泉懦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼疹瘦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼崩哩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起言沐,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤邓嘹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后呢灶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吴超,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年鸯乃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲸阻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缨睡,死狀恐怖鸟悴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奖年,我是刑警寧澤细诸,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站陋守,受9級(jí)特大地震影響震贵,放射性物質(zhì)發(fā)生泄漏利赋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一猩系、第九天 我趴在偏房一處隱蔽的房頂上張望媚送。 院中可真熱鬧,春花似錦寇甸、人聲如沸塘偎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吟秩。三九已至,卻和暖如春绽淘,著一層夾襖步出監(jiān)牢的瞬間涵防,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工沪铭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留武学,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓伦意,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親硼补。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驮肉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容