React组件通讯

2,916 阅读4分钟

首先我们得先了解到为什么需要组件通讯

  • 组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。
  • 在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。
  • 而在这个过程中,多个组件之间不可避免的要共享某些数据
  • 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯

React组件通讯主要有三种方式

1、父子组件之间

2、兄弟组件之间

3、跨组件层级

一、父子组件之间通讯

父子组件之间的通讯主要分为两种情况

  1. 父传子
  • 首先我们讲一下函数式组件的父传子

    函数式组件的父传子主要分为5步

    1.在函数式组件外导入 import { useState } from 'react'
    2.在函数式组件类  const [num, setNum] = useState(0) 这样我们就给num赋予了初始值
    3.在子组件标签上定义 <Son num={num}></Son>
    4.在子组件内部的函数式参数上写上实参props
    5.直接调用 props.num
    

    11.12(01).png

    以下为函数式中父组件的代码

       import { useState } from 'react' //引入useState 函数
       import reactDom from 'react-dom' 
       import Son from './son'
       export default function Father () {
         const [num, setNum] = useState(0) // 0 是初始值 返回值是一个数组
         console.log(setNum)// 修改状态的函数setNum
         return (
               <div>
                   父组件
                   <Son num={num}>
                       <span>
                           children的值
                       </span>
                   </Son>
               </div>
         )
       }
       reactDom.render(<Father></Father>, document.getElementById('root'))
       
    

    子组件代码

     export default function son (props) {
     const { num } = props
     return (
           <div>
               子组件:{num}
               子组件内部的:{ children }
           </div>
     )
    }
    
  • 类组件父传子

    类组件组件的父传子主要分为3步

     1.在类组件中的state里创建一个初始值state={ num: 0 }        
     2.在子组件标签上定义<Son num={this.state.num}></Son>
     3.在子组件标签内部使用 this.props.num
     
    

    以下是类组件中父组件的代码

    import { Component } from 'react'
    import reactDom from 'react-dom'
    import Son from './son'
    export default class Father extends Component {
        state={ //创建一个初始值
          num: 0
        }
    
        render () {
          const { num } = this.state //解构
          return (
                <div>
                    父组件:{num}
                    <Son num={num}></Son>
                </div>
          )
        }
    }
    reactDom.render(<Father></Father>, document.getElementById('root'))
    

    子组件代码

    /* eslint-disable react/prop-types */  //eslint报错,需要验证传入的值,这里就不做校验了
    import { Component } from 'react'
    
    export default class son extends Component {
      render () {
        const { num } = this.props //解构传入的值
        return (
                <div>
                    子组件:
                    {num}
                </div>
        )
      }
    }
    
  1. 子传父

子传父之间的传值归根结底就是在父组件中定义一个函数,然后传到子组件后进行调用,也是一种父传子的表现

  • 以下为函数式组件的子传父(类组件也类似)

父组件

    import { useState } from 'react'
    import reactDom from 'react-dom'
    import Son from './son'
    export default function Father () {
      const [num, setNum] = useState(0)
      //   console.log(setNum)
      const fn = () => { //定义一个函数
        setNum(num + 1)  //调用修改数据的方法
      }
      return (
            <div>
                父组件
                <Son num={num} fn={fn}></Son> //将函数传入子组件
            </div>
      )
    }
    reactDom.render(<Father></Father>, document.getElementById('root'))
    

子组件

    export default function son (props) {
      const { num, fn } = props
      return (
            <div>
                子组件:{num}
                <button onClick={fn}>+1</button> //子组件内调用
                注意!!!  如果需要传入参数 onClick={()=>{fn(参数)}}
                //避免出现加载就触发
            </div>
      )
    }

props可以传递:数字, 字符串, 布尔类型, 数组, 对象, 函数, jsx

二、兄弟组件之间

在react中其实不存在兄弟组件之间的传值,涉及到的兄弟组件之间的传值都会状态提升

  • 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态

  • 思想:状态提升

  • 公共父组件职责:

    • 提供共享状态
    • 提供操作共享状态的方法
  • 要通讯的子组件只需通过 props 接收状态或操作状态的方法

11.12(02).png

三、跨组件层级

image.png

1、类组件的跨组件传值

类跨组件之间的传值主要有三个步骤:

  1. 导入并调用createContext方法,从结果中解构出 Provider, Consumer 组件

      import { createContext } from 'react'
      const { Provider, Consumer } = createContext()
    
  2. 使用 Provider 组件包裹根组件,并通过 value 属性提供要共享的数据

     return (
     <Provider value={ 这里放要传递的数据 }>
          <根组件的内容/>
     </Provider>
     )
    
  3. 在任意后代组件中,使用第1步中导出的Consumer组件包裹整个组件

     return (
          <Consumer>
          {
        (data) => {
          // 这里的形参data 就会自动接收Provider中传入的数据
          // console.log(data)
          return <组件的内容>
          }
      }
    </Consumer>
    )
    
    

2、函数组件的跨组件传值

函数跨组件之间的传值主要有三个步骤:

  1. 导入并调用createContext方法,得到Context对象,导出

      import { createContext } from 'react'
      export const Context = createContext()
    
  2. 使用 Provider 组件包裹根组件,并通过 value 属性提供要共享的数据

       return (
        <Context.Provider value={ 这里放要传递的数据 }>
              <根组件的内容/>
        </Provider>
      )
    
  3. 在任意后代组件中,如果希望获取公共数据: 导入useContext;调用useContext(第一步中导出的context) 得到value的值

     import React, { useContext } from 'react'
     import { Context } from './index'
      const 函数组件 = () => {
          const 公共数据 = useContext(Context)
          return ( 函数组件的内容 )
      }