美文网首页
react组件之间的通信

react组件之间的通信

作者: 剑老师 | 来源:发表于2022-06-17 22:32 被阅读0次

本文首发于公众号【一个老码农】

react组件之间的通信,大致可以分为以下几类

  • 父传子
  • 子传父
  • 兄弟组件之间的通信
  • 任意组件之间的通信
  • 数据全局共享

下面我就来正式聊一下react组件之间有哪些通信方式,并且都是怎样进行通信的,,语言我们用react + typescript

1.父传子

  • props

props传递数据是我们react开发过程中最常用的一种方式,可以把父组件的数据传递给子组件,下面我们就用代码演示一下:

父组件代码:

import React from 'react';
import ChildA from './ChildA';

function App() {
  return (
    <div>
      <ChildA title='父传子数据'></ChildA>
    </div>
  )
}

export default App

子组件代码:

interface ChildAProps {
    title: string
}
const ChildA: React.FC<ChildAProps> = ({title}) => {
    return <div>{title}</div>
}

export default ChildA
  • useContext

useContext传递的数据,在Context.Provider的所有子组件中都可以获取到,value一旦更新,所有子组件也会同步更新

父组件代码:

import React from 'react';
import ChildB from './ChildB';

export const Context = React.createContext<String>('')

function App() {
  return (
    <Context.Provider value={'context传值'}>
      <div>
       <ChildB></ChildB>
      </div>
    </Context.Provider>
  )
}

export default App

子组件代码:

import { useContext } from "react"
import { Context } from "./App"

const ChildB = () => {

    const title = useContext(Context)

    return <div>
        这是ChildB {title}
    </div>
}

export default ChildB

2. 子传父

  • Props回调函数

向子组件Props中传一个函数,在子组件需要向父组件传递数据时,调用此函数即可

子组件代码:

interface ChildAProps {
    title?: string
    call?: (param: string) => void
}
const ChildA: React.FC<ChildAProps> = ({title, call}) => {
    return <div onClick={()=>{
        call && call('回传参数')
    }}>这是ChildA {title}</div>
}

export default ChildA

父组件代码:

import React from 'react';
import ChildA from './ChildA';

function App() {
  return (
      <div>
       <ChildA call={(v)=>{
         console.log(`子组件传过来的值 ${v}`)
       }}></ChildA>
      </div>
  )
}

export default App

  • useRef函数调用

ref的方式可以为父组件提供一个可以调用子组件的函数,在子组件被调用的函数中可以返回相应的数据至父组件,父组件则需要在子组件的Props中传入一个ref

子组件代码:

import { MutableRefObject, useImperativeHandle } from "react"

export interface ChildDCurrent {
    refresh: () => string
}

interface ChildDProps {
    cref: MutableRefObject<ChildDCurrent>
}

const ChildD: React.FC<ChildDProps> = ({cref}) => {

    useImperativeHandle(cref, ()=>({
        refresh: () => {
            return '123'
        }
    }))

    return <div></div>
}

export default ChildD

父组件代码:

import { MutableRefObject, useRef } from "react"
import ChildD, { ChildDCurrent } from "./ChildD"

const ChildC = () => {

    const ref = useRef() as MutableRefObject<ChildDCurrent>

    return <div>
        <button onClick={()=> {
            // ChildD传过来的数据
            const title = ref.current.refresh()
            console.log(`子组件传递过来的数据 ${title}`)
        }}>
            点击刷新
        </button>
        <ChildD cref={ref}></ChildD>
    </div>
}

export default ChildC

3.兄弟组件之间的通信

兄弟组件之间的数据传递,可以利用组件的Props以及Props回调函数来进行,而这种使用方法通信的前提是:必须要有共同的父组件

子组件代码:

interface ChildFProps {
    update: (title: string) => void
}
const ChildF: React.FC<ChildFProps> = ({update}) => {
    return <div onClick={() => {
        update('abcde')
    }}>ChildF</div>
}
export default ChildF


interface ChildGProps {
    title: string
}
const ChildG: React.FC<ChildGProps> = ({title}) => {
    return <div>ChildG {title}</div>
}
export default ChildG

父组件代码:

import { useState } from "react"
import ChildF from "./ChildF"
import ChildG from "./ChildG"

const ComE = () => {
    const [updateValue, setUpdateValue] = useState('')
    return <div>
        <ChildF update={(v) => {
            setUpdateValue(v)
        }}></ChildF>
        <ChildG title={updateValue}></ChildG>
    </div>
}
export default ComE

4.任意组件之间的通信

  • 观察者

如果组件之间没有共同的父组件,那我们就可以用观察者进行组件之间的通信,这个时候我们就需要用到第三方的插件events。下面我们讲下如何用events实现组件间的通信。

首先我们需要执行以下命令安装event

yarn add events

代码:
安装成功后,我们新建一个event.js文件,导出一个全局对象

import EventEmitter from "events";

export default new EventEmitter()

接收数据的组件代码:

import { useEffect, useState } from "react"
import event from "./class/event"

const ChildI = () => {
    const [message, setMessage] = useState('')
    useEffect(() => {
        //监听消息
        event.addListener('message', (message) => {
            setMessage(message)
        })
        return () => {
            event.removeListener('message', (message) => {
                console.log(message)
            })
        }
    })

    return <div>{message}</div>
}

export default ChildI

发送数据的组件代码:

import event from "./class/event"

const  ChildJ = () => {
    return <div>
        <button onClick={() => {
            //发送消息
            event.emit('message','这是我发的消息')
        }}>发送消息</button>
    </div>
}

export default ChildJ

5.各组件数据全局共享

  • window挂载属性

全局数据的共享,如果比较简单的数据,我们可以在window上挂载属性。但是在typeScript中,因为Window类中没有对应的属性,所以会提示报错,我们可以用以下办法解决:

src中创建一个@types文件夹,在@types文件夹下面新建一个index.d.ts文件,代码如下:

interface Window {
    customTitle: string
}

有了以上代码之后就可以在任意地方用以下代码赋值:

window.customTitle = 'xxx'

取值就用下面代码:

const customTitle = window.customTitle
console.log(customTitle)
  • 自定义单例

上面的window以及更上面的观察者其实都是一个单例,window挂载属性虽然方便,但是违背了设计模式的单一原则,而且并不利于代码管理和维护。在开发中,个人其实还是建议自定义一个单例进行管理。

我们新建一个class,并导出一个全局对象

export class Single {
    title?: string
}

export default new Single()

使用时,我们这样写:

import single from './class/Single';
//赋值
single.title = 'abc'

//取值
const title = single.title
console.log(title)

当然,做为一个习惯其它强类型语言的程序员,我们更熟悉这种写法:

export class Single {
    private static instance: Single
    
    public title: string

    private constructor(title: string) {
        this.title = title
    }

    /**
     * 获取单例对象
     */
    public static getInstance() {
        if (!this.instance) {
            this.instance = new Single('')
        }
        return this.instance
    }
}

使用时这样使用:

//赋值时这样写
Single.getInstance().title = 'xxxx'

//取值使用这样写
const title =  Single.getInstance().title
console.log(title)

原文地址

相关文章

  • 总结

    React组件之间的通信方式 1.父组件向子组件通信 React数据流动是单向的,通过props传递 2.子组件向...

  • React Native 架构之 Redux介绍

    React 在 React 中,UI 以组件的形式来搭建,组件之间可以嵌套组合。另,React 中组件间通信的数据...

  • React02-组件通信

    React父子组件之间如何通信父组件传一个函数给子组件,子组件在适当的时候调用这个函数React爷孙组件之间如何通...

  • 干货博客集

    基础 webpack4.x 入门一篇足矣 react组件通信方式汇总 vue组件之间的通信 原生小程序组件通信 w...

  • React 组件件通信2——非父子组件间通信

    孙辈级通信 当需要让子组件跨级访问信息时候,我们可以通过之前那篇React 组件之间的通信1——之父子之间的通信那...

  • 「React Native」Event Bus,消息总线

    (一)父子间组件通信:   一般使用props,回调函数进行通信。(二)跨组件之间通信:  (1)React Na...

  • 深入React技术栈:组件间通信

    我们知道React的组件之间是相互独立的,组件之间的通信可以方便数据的传递和交流,那么在组件之间的通信有以下三种方...

  • react组件之间通信

    很感谢https://segmentfault.com/u/cwl提供的答案React 组件间通讯 说 React...

  • React组件之间的通讯

    在 React 中,UI 以组件的形式来搭建,组件之间可以嵌套组合。另,React 中组件间通信的数据流是单向的,...

  • React组件之间的通信

    父传子 就是父组件传递值给子组件,这个一般用props就可以完成例如: 通过以上方法即可访问。 子传父 问题引入现...

网友评论

      本文标题:react组件之间的通信

      本文链接:https://www.haomeiwen.com/subject/zonhvrtx.html