组件通讯

发布时间 2023-08-23 08:36:38作者: chichi0002

1. 组件通讯

1.1 props

  1. 主要用于父传子,只能一级一级传递

  2. 传递数据的方法:属性名={值},属性名自定义

  3. 如果是函数组件接收数据,则通过形参props接收数据

  4. props是对象{arr:[...]},对象上的属性就是传递数据时,组件上的属性

  5. 如果是类组件接收数据,使用this.props

  6. props可以传递任何类型的数据(普通的数据类型、虚拟dom、组件类型、组件实例)

  7. props数据是只读的,不要修改

  8. 批量传递:<Text {...obj} />===>

  9. 写在组件子节点的内容,默认为props对象中children属性的值

    <Text >测试</Text>
    function Text(props){
    	// 显示‘测试’两个字    
        return <div> {props.children}</div>
    }
    

1.2 context

  1. react提供的方案,自上而下传递,允许跨级传递(爷===>父爷===>孙

  2. 适用于父级组件传递数据给孙组件,父组件===》孙组件

  3. 步骤:App => Far => Son

  4. 传递数据:

    1. 创建context对象:const context = React.createContext( '默认值'),默认值在不写 Provider 的时候生效

    2. 解构出Provider: const {Provider} = context

    3. 用Provider包裹整个组件

    4. 要传递的数据通过给Provider添加属性value的值添加

      <Provider value={data}>
      	<div>
          	App
      		<Far></Far>
          </div>
      </Provider>
      
  5. 接收数据:方式一

    //利用context接收数据:
    const  {Consumer} = context// 结构出Consumer
    export default class Son extends Component{
        render(){
            return (
            	<Consumer>
                	{(data)=>{
                return <div>Son,{data}</div>
            }}
                </Consumer>
            )
        }
    }
    
  6. 接收数据:方式二

    export default class Son extends Component{
     // 给接收数据的组件添加一个静态属性 contextType
        static contextType =context
    	render(){
       		// 使用this.context,这就是传递过来的数据     
            return <div>Son:{this.context}</div>
        }
    }
    

1.3 pubsub-js

  1. pubsub-js是一个独立的js库,props和context是react技术

  2. 组件之间不需要有嵌套关系,props和context需要组件之间有嵌套关系

  3. 是一个发布订阅模式的js库,传递数据的组件就是发布者,接收数据的组件就是订阅者

  4. 一个组件既可以是发布者(传递数据),也可以是订阅者(接收数据)

  5. 一个发布者(传递数据)可以对应多个订阅者(接收数据)

  6. 操作步骤:

    1. 安装:npm i publish-js

    2. 导入对象,提高发布 / 订阅功能:import PubSub from 'pubsub-js'

    3. 提供的一些方法

      1. 接收数据:(订阅)PubSub.subscribe(话题,callback),一般正在挂载的时候

        // subId:方法的返回值,当前订阅的唯一标识符,用于清除当前订阅,一般在组件挂载时订阅
        var subId = PubSub.subscribe('car' , function(meassage , data){
        // meassage:话题;data接收的数据
            console.log(data)
        })
        
      2. 传递数据:(发布)PubSub.Publish("话题",data)

        PubSub.publish('car','Hello Word!')
        // car:是话题
        // Hello Word!:是需要传递的数据内容
        
      3. 取消指定的订阅(获取数据),一般在组件卸载的时候,清除之前的订阅数据,节约内存

        PubSub.unsubscribe(subId)
        // 利用订阅的唯一标识符
        
      4. 取消某个话题的所有订阅

        PubSub.unsubscribe(话题)
        
      5. 取消所有订阅

        PubSub.clearAllSubscriptions()
        
  7. 为什么要取消订阅?

    // 因为pubsub-js内部,管理了一个对象.每一次订阅的就是往对象中添加属性,值是数组,数组中存放了当前话题所对应的所有订阅的回调函数
       {
          car: [callback1, callback2]
       }
     //如果组件卸载了,但是组件的订阅还在,这就浪费了内存. 所以组件卸载的时候要清除订阅.
    
    
    

高阶组件HOC

解决代码复用问题,将相同的state和逻辑封装起来

操作步骤:

  1. 创建一个公共组件(Common)
  2. 在公共组件(Common)中定义相同的状态和逻辑
  3. 在公共组件(Common)中,给每个需要使用公共组件中的状态和逻辑的组件创建一个组件实例