詳解React的組件通訊

組件通訊介紹

內容

  • 組件是獨立且封閉的單元,默認情況下,隻能使用組件自己的數據。
  • 在組件化過程中,我們將一個完整的功能拆分成多個組件,以更好的完成整個應用的功能。
  • 而在這個過程中,多個組件之間不可避免的要共享某些數據
  • 為瞭實現這些功能,就需要打破組件的獨立封閉性,讓其與外界溝通。這個過程就是組件通訊。

三種方式

  • 父子組件之間
  • 兄弟組件之間
  • 跨組件層級

小結

組件中的狀態是私有的,也就是說,組件的狀態隻能在組件內部使用,無法直接在組件外使用

組件通訊-父傳子

內容:

  • 父組件提供要傳遞的state數據
  • 給子組件標簽添加屬性,值為 state 中的數據
  • 子組件中通過 props 接收父組件中傳遞的數據

核心代碼

父組件提供數據並且傳遞給子組件

class Parent extends React.Component {
    state = { lastName: '王' }
    render() {
        return (
            <div>
                傳遞數據給子組件:<Child name={this.state.lastName} />
            </div>
        )
    }
}

子組件接收數據

function Child(props) {
	return <div>子組件接收到數據:{props.name}</div>
}

組件通訊-子傳父

思路

利用回調函數,父組件提供回調,子組件調用,將要傳遞的數據作為回調函數的參數。

步驟

1.父組件

1.定義一個回調函數f(將會用於接收數據)

2.將該函數f作為屬性的值,傳遞給子組件

2.子組件

1.通過 props 獲取f

2.調用f,並傳入將子組件的數據

核心代碼

父組件提供函數並且傳遞給子組件

class Parent extends React.Component {
    state: {
      num: 100
    }
    f = (num) => {
        console.log('接收到子組件數據', num)
    }
    render() {
        return (
            <div>
            	子組件:<Child f={this.f} />
            </div>
        )
    }
}

子組件接收函數並且調用

class Child extends React.Component {
    handleClick = () => {
      // 調用父組件傳入的props,並傳入參數
    	this.props.f(100)
    }
    return (
    	<button onClick={this.handleClick}>點我,給父組件傳遞數據</button>
    )
}

小結

子傳父:在子組件中調用從父組件中定義的方法,並根據需要傳入參數

組件通訊-兄弟組件

在React中沒有確定的兄弟組件,就沒有這個說法哈,有的隻有狀態提升.

思路

  • 將共享狀態提升到最近的公共父組件中,由公共父組件管理這個狀態
  • 思想:狀態提升
  • 公共父組件職責:
    • 提供共享狀態
    • 提供操作共享狀態的方法
  • 要通訊的子組件隻需通過 props 接收狀態或操作狀態的方法

核心代碼

parent.js

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Jack from './Jack'
import Rose from './Rose'
class App extends Component {
  // 1. 狀態提升到父組件
  state = {
    msg: '',
  }
  render() {
    return (
      <div>
        <h1>我是App組件</h1>
        <Jack say={this.changeMsg}></Jack>
        {/* 2. 把狀態給子組件顯示 */}
        <Rose msg={this.state.msg}></Rose>
      </div>
    )
  }
  changeMsg = (msg) => {
    this.setState({
      msg,
    })
  }
}
// 渲染組件
ReactDOM.render(<App />, document.getElementById('root'))

Son1.js

import React, { Component } from 'react'
export default class Jack extends Component {
  render() {
    return (
      <div>
        <h3>我是Jack組件</h3>
        <button onClick={this.say}>說</button>
      </div>
    )
  }
  say = () => {
    this.props.say('you jump i look')
  }
}

Son2.js

import React, { Component } from 'react'
export default class Rose extends Component {
  render() {
    return (
      <div>
        <h3>我是Rose組件-{this.props.msg}</h3>
      </div>
    )
  }
}

組件通訊 -跨級組件通訊

想在vue中使用跨級組件通訊,需要使用Context

使用Context的步驟

共三步:

1.導入並調用createContext方法,從結果中解構出 Provider, Consumer 組件

import { createContext } from 'react'
const { Provider, Consumer } = createContext()

2.使用 Provider 組件包裹根組件,並通過 value 屬性提供要共享的數據

return (
  <Provider value={ 這裡放要傳遞的數據 }>
  	<根組件的內容/>
  </Provider>
)

3.在任意後代組件中,使用第2步中導出的Consumer組件包裹整個組件

return (
	<Consumer>
  	{
      (data) => {
      	// 這裡的形參data 就會自動接收Provider中傳入的數據
        // console.log(data)
      	return <組件的內容>
    	}
    }
  </Consumer>
)

落地代碼

建立context.js文件

import { createContext } from 'react'
const { Provider, Consumer } = createContext()
export { Consumer, Provider }

改造根組件

import { Provider } from './context'
render () {
    return (
      <Provider value={{ num: this.state.num }}>
        <div>
          根組件, num: {this.state.num}
          <Parent />
          <Uncle />
        </div>
      </Provider>
    )
  }

改造後代組件 Uncle.js

import React from 'react'
import { Consumer } from './context'
export default class Uncle extends React.Component {
  render () {
    return (
      <Consumer>
        {(data) => {
          return <div>我是Uncle組件, {data.num}</div>
        }}
      </Consumer>
    )
  }
}

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: