React中實(shí)現(xiàn)組件通信的幾種方式小結(jié)
前言
下面我們認(rèn)識(shí)react組件通信的幾種方式。
在構(gòu)建復(fù)雜的React應(yīng)用時(shí),組件之間的通信是至關(guān)重要的。從簡(jiǎn)單的父子組件通信到跨組件狀態(tài)同步,不同組件之間的通信方式多種多樣。
1. 父子組件通信
父子組件通信是 React 中最基本的通信方式之一。在這種模式下,數(shù)據(jù)是從父組件通過(guò) props 傳遞給子組件的,子組件接收到 props 后進(jìn)行渲染或其他操作。
特點(diǎn):
單向數(shù)據(jù)流:數(shù)據(jù)從父組件流向子組件,子組件無(wú)法直接修改父組件傳遞過(guò)來(lái)的 props。
簡(jiǎn)單明了:適用于父子組件之間的簡(jiǎn)單數(shù)據(jù)傳遞和交互。
可維護(hù)性高:因?yàn)閿?shù)據(jù)流清晰,易于追蹤和調(diào)試。
父組件:
// 父組件 import React, { Component } from 'react' import CChild from "./components/C-Child" export default class CApp extends Component { state = { msg: '這是父組件的數(shù)據(jù)' } render() { return ( <div> <h2>父組件</h2> <CChild msg={this.state.msg} /> </div> ) } }
子組件:
// 子組件 import React, { Component } from 'react' export default class CChild extends Component { render() { return ( <div> <h4>子組件</h4> <p>{this.props.msg}</p> </div> ) } }
2. 子父組件通信
子父組件通信是指子組件向父組件傳遞數(shù)據(jù)或事件的過(guò)程。通常通過(guò)在子組件中定義回調(diào)函數(shù),并將其作為 props 傳遞給子組件來(lái)實(shí)現(xiàn)。
特點(diǎn):
子組件向父組件傳遞數(shù)據(jù)或事件:子組件通過(guò)調(diào)用父組件傳遞的回調(diào)函數(shù),向父組件傳遞數(shù)據(jù)或觸發(fā)事件。
靈活性高:可以在需要的時(shí)候向父組件傳遞數(shù)據(jù),實(shí)現(xiàn)靈活的交互。
PApp
組件定義了一個(gè)callback
方法,這個(gè)方法用于接收子組件傳遞的數(shù)據(jù)。
父組件 PApp:
在 render
方法中,PApp
渲染一個(gè) PChild
子組件,并將 callback
方法作為 cb
屬性傳遞給子組件。
//父組件PApp import React, { Component } from 'react' import PChild from './components/PChild' export default class PApp extends Component { state = { msg: '' } callback = (newMsg) => { console.log('拿到子組件的數(shù)據(jù): ' + newMsg); this.setState({ msg: newMsg }) } render() { return ( <div> <h2>父組件 --- {this.state.msg}</h2> // 將回調(diào)函數(shù)傳遞給子組件 <PChild cb={this.callback} /> </div> ) } }
子組件 PChild:
PChild
組件包含了一個(gè)狀態(tài)msg
,代表子組件的數(shù)據(jù)。PChild
組件有一個(gè)按鈕,當(dāng)按鈕被點(diǎn)擊時(shí),觸發(fā)handler
方法。handler
方法調(diào)用了父組件傳遞的回調(diào)函數(shù)cb
,并將子組件的狀態(tài)數(shù)據(jù)msg
作為參數(shù)傳遞給父組件。
//子組件PChild import React, { Component } from 'react' export default class PChild extends Component { state = { msg: '來(lái)自子組件的數(shù)據(jù)' } // 處理按鈕點(diǎn)擊事件,調(diào)用父組件傳遞的回調(diào)函數(shù) handler = () => { this.props.cb(this.state.msg)// 將子組件的數(shù)據(jù)傳遞給父組件 } render() { return ( <div> <h4>子組件</h4> <button onClick={this.handler}>傳遞</button> </div> ) } }
使用示例
點(diǎn)擊傳遞按鈕前:
點(diǎn)擊傳遞按鈕后:
3. 兄弟組件通信
兄弟組件通信是指不具有直接父子關(guān)系的兩個(gè)組件之間進(jìn)行數(shù)據(jù)傳遞和交互的過(guò)程。在 React 中,通常需要通過(guò)共享父組件來(lái)實(shí)現(xiàn)兄弟組件之間的通信。
注意:兄弟組件使用共同的父類作為橋梁,本質(zhì)是父子之間通信。
BApp 組件:
BApp
組件是整個(gè)應(yīng)用的父組件,它維護(hù)著一個(gè)狀態(tài)message
,初始值為'hello'
。在
render
方法中,BApp
返回了一個(gè)包含標(biāo)題、BrotherA
和BrotherB
組件的 JSX 結(jié)構(gòu)。將
message
狀態(tài)作為BrotherB
組件的 props 傳遞給它。
import React, { Component } from 'react'; import BrotherA from "./components/BrotherA"; import BrotherB from "./components/BrotherB"; class BApp extends Component { state = { message: 'hello' } // 回調(diào)函數(shù),用于更新 message 狀態(tài) // 注意:React 中狀態(tài)更新通常使用 setState 方法 fn = (newMsg) => { console.log('父組件收到:' + newMsg); this.setState({ message: newMsg }) } render() { return ( <div> <h1>父組件</h1> {/* 將 fn 方法作為 props 傳遞給 BrotherA 組件 */} <BrotherA cb={this.fn} /> {/* 將 message 狀態(tài)作為 props 傳遞給 BrotherB 組件 */} <BrotherB message={this.state.message} /> </div> ); } } export default BApp;
- BrotherA 組件:
- 定義了一個(gè)局部變量
msg
,它的值是字符串 '來(lái)自子組件A的數(shù)據(jù)'。 - 定義了一個(gè)函數(shù)
handle
,用于處理點(diǎn)擊事件。當(dāng)組件標(biāo)題被點(diǎn)擊時(shí),會(huì)調(diào)用props
中傳遞的cb
函數(shù),并傳遞msg
變量作為參數(shù)。 - 返回一個(gè)包含標(biāo)題的 JSX 結(jié)構(gòu),在標(biāo)題上設(shè)置了點(diǎn)擊事件處理函數(shù)為
handle
。
import React from 'react'; const BrotherA = props => { const msg = '來(lái)自子組件A的數(shù)據(jù)' const handle = () => { props.cb(msg) } return ( <div> <h4 onClick={handle}>子組件A</h4> </div> ); }; export default BrotherA;
BrotherB 組件:
BrotherB
組件接收一個(gè)名為message
的 prop,它來(lái)自于BApp
的狀態(tài)。- 在組件中顯示了一個(gè)標(biāo)題和
message
的值。
import React from 'react'; const BrotherB = props => { return ( <div> <h4>子組件B -- {props.message}</h4> </div> ); }; export default BrotherB;
接下來(lái)我們驗(yàn)證一下:點(diǎn)擊子組件A
點(diǎn)擊之后如圖結(jié)果:
4. 使用Context進(jìn)行跨層級(jí)組件通信
當(dāng)組件層級(jí)較深或通信的組件距離較遠(yuǎn)時(shí),可以使用React的Context API進(jìn)行跨層級(jí)通信。Context允許我們?cè)诮M件樹中傳遞數(shù)據(jù),而不必手動(dòng)通過(guò)Props一層層傳遞。
創(chuàng)建:
- 使用
React.createContext()
創(chuàng)建上下文對(duì)象 - 并在組件中使用
Provider
提供數(shù)據(jù), - 子組件通過(guò)
Consumer
或useContext
獲取數(shù)據(jù)。
context.js
import React from 'react'; // 創(chuàng)建一個(gè)上下文對(duì)象 const { Provider, Consumer } = React.createContext(); // 導(dǎo)出 Provider 和 Consumer 組件,以便在其他地方使用 export { Provider, Consumer }
BApp
BApp
組件是一個(gè)類組件,它作為數(shù)據(jù)的提供者,使用Provider
組件將數(shù)據(jù)傳遞給它的子組件。在
BApp
組件的render
方法中,通過(guò)Provider
組件的value
屬性傳遞了一個(gè)名為message
的狀態(tài)值
// BApp.jsx import React, { Component } from 'react'; import BrotherB from "./components/BrotherB"; import { Provider } from "./context.js"; class BApp extends Component { state = { message: 'hello react', // 初始化狀態(tài)值 } render() { return ( // 使用 Provider 組件提供數(shù)據(jù) <Provider value={this.state.message}> <div> <h1>父組件</h1> {/* 渲染子組件 */} <BrotherB /> </div> </Provider> ); } } export default BApp;
BrotherB
BrotherB
組件是一個(gè)函數(shù)組件,它作為數(shù)據(jù)的消費(fèi)者,使用Consumer
組件從上層組件(BApp
)獲取數(shù)據(jù)并進(jìn)行渲染。在
BrotherB
組件中,通過(guò)Consumer
組件的子組件函數(shù)來(lái)接收從Provider
傳遞下來(lái)的值,并進(jìn)行相應(yīng)的渲染。
// BrotherB.jsx import React from 'react'; import { Consumer } from '../provider.js'; const BrotherB = props => { return ( // 使用 Consumer 組件消費(fèi)數(shù)據(jù) <Consumer> {value => ( <div> {/* 使用從 Provider 傳遞下來(lái)的值進(jìn)行渲染 */} <h4>子組件B -- {value}</h4> </div> )} </Consumer> ); }; export default BrotherB;
補(bǔ)充
在 Consumer
組件內(nèi)部,我們可以使用函數(shù)作為子組件
- 使用函數(shù)作為子組件:
<Consumer> {value => ( // 在這里可以直接使用 value 進(jìn)行渲染或處理 <div> <h4>子組件B -- {value}</h4> </div> )} </Consumer>
在這個(gè)示例中,<Consumer>
組件的子元素是一個(gè)函數(shù),該函數(shù)接收 value
參數(shù),這個(gè) value
參數(shù)就是從 Provider
傳遞下來(lái)的值。在函數(shù)內(nèi)部,可以直接使用 value
進(jìn)行渲染或處理。
這種方式適用于在 JSX 內(nèi)部直接定義渲染邏輯,通常更易讀,因?yàn)樗苯臃旁诹?<Consumer>
標(biāo)簽內(nèi)部。
效果圖:
這樣,就實(shí)現(xiàn)了 BApp
組件向 BrotherB
組件傳遞數(shù)據(jù)的功能。 Context API 的優(yōu)點(diǎn)之一就是可以讓組件之間直接傳遞數(shù)據(jù),而無(wú)需通過(guò) props 一層層地傳遞,從而簡(jiǎn)化了組件之間的關(guān)系。
到此這篇關(guān)于React中實(shí)現(xiàn)組件通信的幾種方式小結(jié)的文章就介紹到這了,更多相關(guān)React組件通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解對(duì)于React結(jié)合Antd的Form組件實(shí)現(xiàn)登錄功能
這篇文章主要介紹了詳解對(duì)于React結(jié)合Antd的Form組件實(shí)現(xiàn)登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04React Native開發(fā)封裝Toast與加載Loading組件示例
這篇文章主要介紹了React Native開發(fā)封裝Toast與加載Loading組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09從零開始學(xué)習(xí)搭建React腳手架項(xiàng)目
這篇文章主要介紹了從零開始學(xué)習(xí)搭建React腳手架項(xiàng)目,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08React組件設(shè)計(jì)模式之組合組件應(yīng)用實(shí)例分析
這篇文章主要介紹了React組件設(shè)計(jì)模式之組合組件,結(jié)合實(shí)例形式分析了React組件設(shè)計(jì)模式中組合組件相關(guān)概念、原理、應(yīng)用場(chǎng)景與操作注意事項(xiàng),需要的朋友可以參考下2020-04-04React配置Redux并結(jié)合本地存儲(chǔ)設(shè)置token方式
這篇文章主要介紹了React配置Redux并結(jié)合本地存儲(chǔ)設(shè)置token方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01react-routerV6版本和V5版本的詳細(xì)對(duì)比
React-Router5是React-Router6的前一個(gè)版本,它已經(jīng)被React-Router6取代,React-Router 6是一次較大的重大更新,本文就來(lái)介紹一下react-routerV6版本和V5版本的詳細(xì)對(duì)比,感興趣的可以了解一下2023-12-12