通信方式

54 阅读3分钟

一、props父子通信

1.函数式组件

function Children(props) { return (

Children

{props.text}

) }

function Parent(props) { return (

Parent

) }

export default Parent

2.类组件

import {Component} from 'react' class Parent extends Component{ constructor() { super() } render() { return (

Parent

)
} }

class Children extends Component{ constructor() { super() } render() { return (

Children

{this.props.text}

)
} }

export default Parent

二、子向父回调函数通信

1.函数式组件 import { useState} from 'react'

function Parent(props) { const [msg,setMsg] = useState('888') //要这样把值放在state中是因为状态的更新才会导致页面重新渲染组件(后面详细了解页面重新渲染的条件) //msg的初始值为888,setMsg为改变msg的函数,当点击按钮时msg更新为子组件传过来的值 let getMsg = (msg) => { setMsg(msg) } return (

Parent

{msg}

) }

function Children(props) { let handleClick = () => { props.getMsg('儿子传的东西') } return (

Children

<button onClick={handleClick} style={{height:'30px',width:'30px'}}>
) } export default Parent

2.类组件

import {Component} from 'react' class Parent extends Component{ constructor() { super() this.state={ msg:'666' } } getMsg = (msg) => { this.setState({ msg:msg }) } render() { return (

Parent

{this.state.msg}

)
} }

class Children extends Component{ constructor() { super() } handleClick = (msg) => { this.props.getMsg('儿子传的东西') } render() { return (

Children

<button onClick={this.handleClick} style={{height:'30px',width:'30px'}}>
)
} }

export default Parent

三、子向父使用实例(ref)通信

  • 通过react的hooks新特性,useRef、useImperativeHandle、forwardRef来实现

  • useRef:

    • useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数(initialValue)。返回的ref对象在组件的整个生命周期内持续存在。
  • useImperativeHandle

    • useImperativeHandle可以让你在使用ref时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用ref这样的命令时代码。useImperativeHandle应当与forwardRef一起使用。
  • forwardRef

    • React.forwardRef接受渲染函数作为参数。React将使用props和ref作为参数来调用此函数。此函数应返回React节点

import {useState,useRef, useEffect} from 'react' import Children from '@/pages/children'

function Parent(props) { let [msg, setMsg] = useState(222) let childrenRef = useRef(null) useEffect(() => { //获取子组件数据 setMsg(childrenRef.current.msg) childrenRef.current.fn() },[]) return (

Parent

{msg}

) } export default Parent

import { useImperativeHandle, forwardRef} from 'react'

function Children(props, ref) { useImperativeHandle(ref, () => { return { msg:'我是子组件信息', fn:() => { console.log('我是子组件函数') } } }) return (

Children

) }

export default forwardRef(Children)

四、兄弟组件使用共同的props通信

import { useState} from 'react'

function Parent(props) { let [msg, setMsg] = useState('666') let getMsg = (msg) => { setMsg(msg) } return (

Parent

) }

function Children(props) { let handleClick = () => { props.getMsg('兄弟给你传的值') }

return (
    <div>
      <p>Children</p>
      <button onClick={handleClick}>点我</button>
    </div>
)

}

function Children1(props) { return (

{props.msg}
) } export default Parent

五、跨级组件context通信(祖先->后代)

//先创建一个context.js文件 context.js

import React from 'react' let MyContext = React.createContext() export default MyContext

1.函数式组件

import MyContext from '@/utils/context' function Parent() { let {Provider} = MyContext return (

Parent

<Provider value={{text:'good luck'}}>
) }

//第一种接收方式 import MyContext from '@/utils/context' function Children(props) { let {Consumer} = MyContext return (

Children

{ value => ( value.text+'llllll' ) }
) }

//第二种接收方式 import MyContext from '@/utils/context' import {useContext} from 'react' function Children(props) { let {text} = useContext(MyContext) return (

Children

{text}

) }

export default Parent

2.类组件

import {Component} from 'react' import MyContext from '@/utils/context' class Parent extends Component{ constructor() { super() } render() { return (

Parent

<MyContext.Provider value={{text:'good luck'}}> </MyContext.Provider>
)
} }

//第一种接受方式同函数组件的第一种 //第二种接收方式 class Children extends Component{ constructor() { super() } static contextType = MyContext render() { return (

Children

{this.context.text}

)
} }

export default Parent

六、非嵌套组件之间event(事件总线)通信

//先创建一个event.js文件 event.js

import {EventEmitter} from 'events' let eventBus = new EventEmitter() export default eventBus

import eventBus from '@/utils/event' function Article() { let handleClick = () => { eventBus.emit('btnClick','我是event传值') } return (

Parent

<button onClick={handleClick} style={{height:'30px',width:'30px'}}>
) }

export default Article

import eventBus from '@/utils/event' import {useState} from 'react' function Publish() { let [name,setName] = useState('666') //监听 eventBus.addListener('btnClick', msg => { console.log(msg) setName(msg) }) //销毁 eventBus.removeListener('btnClick', msg => { console.log(msg) }) return (

Children

{name}

) }

export default Publish