摘要:首次發(fā)表在個人博客需要組件之進(jìn)行通信的幾種情況父組件向子組件通信子組件向父組件通信跨級組件通信沒有嵌套關(guān)系組件之間的通信父組件向子組件通信數(shù)據(jù)流動是單向的父組件向子組件通信也是最常見的父組件通過向子組件傳遞需要的信息子組件向父組件通信利用
首次發(fā)表在個人博客需要組件之進(jìn)行通信的幾種情況
父組件向子組件通信
子組件向父組件通信
跨級組件通信
沒有嵌套關(guān)系組件之間的通信
1. 父組件向子組件通信React數(shù)據(jù)流動是單向的,父組件向子組件通信也是最常見的;父組件通過props向子組件傳遞需要的信息
Child.jsx
import React from "react"; import PropTypes from "prop-types"; export default function Child({ name }) { returnHello, {name}
; } Child.propTypes = { name: PropTypes.string.isRequired, };
Parent.jsx
import React, { Component } from "react"; import Child from "./Child"; class Parent extends Component { render() { return (2. 子組件向父組件通信); } } export default Parent;
利用回調(diào)函數(shù)
利用自定義事件機(jī)制
回調(diào)函數(shù)實現(xiàn)在子組件中點擊隱藏組件按鈕可以將自身隱藏的功能
List3.jsx
import React, { Component } from "react"; import PropTypes from "prop-types"; class List3 extends Component { static propTypes = { hideConponent: PropTypes.func.isRequired, } render() { return (哈哈,我是List3); } } export default List3;
App.jsx
import React, { Component } from "react"; import List3 from "./components/List3"; export default class App extends Component { constructor(...args) { super(...args); this.state = { isShowList3: false, }; } showConponent = () => { this.setState({ isShowList3: true, }); } hideConponent = () => { this.setState({ isShowList3: false, }); } render() { return ({ this.state.isShowList3 ?); } }: null }
觀察一下實現(xiàn)方法,可以發(fā)現(xiàn)它與傳統(tǒng)回調(diào)函數(shù)的實現(xiàn)方法一樣.而且setState一般與回調(diào)函數(shù)均會成對出現(xiàn),因為回調(diào)函數(shù)即是轉(zhuǎn)換內(nèi)部狀態(tài)是的函數(shù)傳統(tǒng);
3. 跨級組件通信層層組件傳遞props
例如A組件和B組件之間要進(jìn)行通信,先找到A和B公共的父組件,A先向C組件通信,C組件通過props和B組件通信,此時C組件起的就是中間件的作用
使用context
context是一個全局變量,像是一個大容器,在任何地方都可以訪問到,我們可以把要通信的信息放在context上,然后在其他組件中可以隨意取到;使用context
但是React官方不建議使用大量context,盡管他可以減少逐層傳遞,但是當(dāng)組件結(jié)構(gòu)復(fù)雜的時候,我們并不知道context是從哪里傳過來的;而且context是一個全局變量,全局變量正是導(dǎo)致應(yīng)用走向混亂的罪魁禍?zhǔn)?
下面例子中的組件關(guān)系: ListItem是List的子組件,List是app的子組件
ListItem.jsx
import React, { Component } from "react"; import PropTypes from "prop-types"; class ListItem extends Component { // 子組件聲明自己要使用context static contextTypes = { color: PropTypes.string, } static propTypes = { value: PropTypes.string, } render() { const { value } = this.props; return (
List.jsx
import ListItem from "./ListItem"; class List extends Component { // 父組件聲明自己支持context static childContextTypes = { color: PropTypes.string, } static propTypes = { list: PropTypes.array, } // 提供一個函數(shù),用來返回相應(yīng)的context對象 getChildContext() { return { color: "red", }; } render() { const { list } = this.props; return (); } } export default List;{ list.map((entry, index) =>
, ) }
App.jsx
import React, { Component } from "react"; import List from "./components/List"; const list = [ { text: "題目一", }, { text: "題目二", }, ]; export default class App extends Component { render() { return (4. 沒有嵌套關(guān)系的組件通信); } }
使用自定義事件機(jī)制
在componentDidMount事件中,如果組件掛載完成,再訂閱事件;在組件卸載的時候,在componentWillUnmount事件中取消事件的訂閱;使用自定義事件的方式
以常用的發(fā)布/訂閱模式舉例,借用Node.js Events模塊的瀏覽器版實現(xiàn)
下面例子中的組件關(guān)系: List1和List2沒有任何嵌套關(guān)系,App是他們的父組件;
實現(xiàn)這樣一個功能: 點擊List2中的一個按鈕,改變List1中的信息顯示
首先需要項目中安裝events 包:
npm install events --save
在src下新建一個util目錄里面建一個events.js
import { EventEmitter } from "events"; export default new EventEmitter();
list1.jsx
import React, { Component } from "react"; import emitter from "../util/events"; class List extends Component { constructor(props) { super(props); this.state = { message: "List1", }; } componentDidMount() { // 組件裝載完成以后聲明一個自定義事件 this.eventEmitter = emitter.addListener("changeMessage", (message) => { this.setState({ message, }); }); } componentWillUnmount() { emitter.removeListener(this.eventEmitter); } render() { return ({this.state.message}); } } export default List;
List2.jsx
import React, { Component } from "react"; import emitter from "../util/events"; class List2 extends Component { handleClick = (message) => { emitter.emit("changeMessage", message); }; render() { return (); } }
APP.jsx
import React, { Component } from "react"; import List1 from "./components/List1"; import List2 from "./components/List2"; export default class App extends Component { render() { return (); } }
自定義事件是典型的發(fā)布訂閱模式,通過向事件對象上添加監(jiān)聽器和觸發(fā)事件來實現(xiàn)組件之間的通信
總結(jié)父組件向子組件通信: props
子組件向父組件通信: 回調(diào)函數(shù)/自定義事件
跨級組件通信: 層層組件傳遞props/context
沒有嵌套關(guān)系組件之間的通信: 自定義事件
在進(jìn)行組件通信的時候,主要看業(yè)務(wù)的具體需求,選擇最合適的;參考
當(dāng)業(yè)務(wù)邏輯復(fù)雜到一定程度,就可以考慮引入Mobx,Redux等狀態(tài)管理工具
reactjs官方文檔
深入React技術(shù)棧
React中組件間通信的幾種方式
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90314.html
摘要:在使用的過程中,不可避免的需要組件間進(jìn)行消息傳遞通信,組件間通信大體有下面幾種情況父組件向子組件通信子組件向父組件通信非嵌套組件間通信跨級組件之間通信父組件向子組件通信父組件通過向子組件傳遞,子組件得到后進(jìn)行相應(yīng)的處理。 在使用 React 的過程中,不可避免的需要組件間進(jìn)行消息傳遞(通信),組件間通信大體有下面幾種情況: 父組件向子組件通信 子組件向父組件通信 非嵌套組件間通信 跨...
摘要:在使用的過程中,不可避免的需要組件間進(jìn)行消息傳遞通信,組件間通信大體有下面幾種情況父組件向子組件通信子組件向父組件通信非嵌套組件間通信跨級組件之間通信父組件向子組件通信父組件通過向子組件傳遞,子組件得到后進(jìn)行相應(yīng)的處理。 在使用 React 的過程中,不可避免的需要組件間進(jìn)行消息傳遞(通信),組件間通信大體有下面幾種情況: 父組件向子組件通信 子組件向父組件通信 非嵌套組件間通信 跨...
摘要:父組件聲明自己支持父組件提供一個函數(shù),用來返回相應(yīng)的對象子組件聲明自己需要使用我胡漢三又回來了點擊我如果是父組件向子組件單向通信,可以使用變量,如果子組件想向父組件通信,同樣可以由父組件提供一個回調(diào)函數(shù),供子組件調(diào)用,回傳參數(shù)。 在使用 React 的過程中,不可避免的需要組件間進(jìn)行消息傳遞(通信),組件間通信大體有下面幾種情況: 父組件向子組件通信 子組件向父組件通信 跨級組件之間...
摘要:父子組件通信父子間通信的幾種情況父組件向子組件通信子組件向父組件通信跨級組件通信兄弟組件通信父組件向子組件通信由于是單向數(shù)據(jù)流向的,父組件一般通過向子組件傳遞相關(guān)的一些信息來看一下下面這個例子,在這里我封裝了一個組件,它的顯示與取消的狀態(tài)交 react父子組件通信 react父子間通信的幾種情況 父組件向子組件通信 子組件向父組件通信 跨級組件通信 兄弟組件通信 父組件向子組件通信...
摘要:并總結(jié)經(jīng)典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關(guān)注微信小程序的開發(fā)和面試問題,由基礎(chǔ)到困難循序漸進(jìn),適合面試和開發(fā)小程序。并總結(jié)vue React html css js 經(jīng)典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...
閱讀 1466·2021-09-02 13:57
閱讀 1882·2019-08-30 15:55
閱讀 2419·2019-08-30 15:54
閱讀 2259·2019-08-30 15:44
閱讀 2741·2019-08-30 13:18
閱讀 491·2019-08-30 13:02
閱讀 660·2019-08-29 18:46
閱讀 1673·2019-08-29 11:25