React组件通信详解

作者:袖梨 2026-09-04

在前端开发内容学习中,React 组件通信详解:父传子、子传父、兄弟通信与 Context是常见主题。很多人在阅读时会遇到概念分散、步骤不清和注意点难以归纳的问题。本文按照基础概念、操作流程和关键细节,对相关内容进行整理。

React 最核心的思想之一是:

React 组件通信详解:父传子、子传父、兄弟通信与 Context

组件化开发

一个页面通常由很多组件组成:

App

├── Header
├── Sidebar
├── Main
│   ├── UserInfo
│   └── ProductList
└── Footer

组件拆分后,就会出现一个问题:

组件之间如何传递数据?

这就是:

组件通信(Component Communication)

为什么需要组件通信?

例如:

用户信息

↓

Header显示用户名

↓

Sidebar显示头像

↓

Main显示个人资料

这些组件都需要同一份数据。

所以:

组件之间必须能够共享数据

React 中常见通信方式

React 项目中最常见的通信方式有:

父传子

↓

子传父

↓

兄弟组件通信

↓

跨组件通信(Context)

学习顺序也基本如此。


什么是 State(状态)?

在学习组件通信之前,我们需要先理解 React 中一个很重要的概念:

State(状态)

很多初学者会把 State 和普通变量混淆,其实它们最大的区别就在于:

State 会驱动界面更新

普通变量不会

例如:

const count = 0

修改:

count++

页面并不会重新渲染。

但是:

const [count, setCount] = useState(0)

调用:

setCount(count + 1)

React 会重新渲染组件,页面也会同步更新。

所以,可以这样理解:

State 本身就是数据

只不过它是:

会变化的数据

并且:

React 会监听它的变化

所以,更准确地说:

状态(State)

=

会影响界面渲染的数据

或者一句话记住:

改变 State

=

改变数据

+

通知 React 更新页面

也就是说:

State(状态)

本身就是数据

只不过它是:

"会变的数据"

改变状态

=

改变数据内容

+

触发界面更新

一、父传子

最简单也是最常见的通信方式。

场景:

父组件有数据

子组件需要使用

实现原理

父组件:

通过属性传递数据

子组件:

通过 props 接收数据

示例

父组件:

import Child from './Child'

function App() {

  const name = 'Rose'

  return (
    <Child name={name} />
  )
}

子组件:

function Child(props) {

  return (
    <h1>{props.name}</h1>
  )
}

export default Child

输出:

Rose

props 是什么?

props:

properties(属性)

可以理解为:

父组件传递给子组件的数据包

例如:

<Child
  name="Rose"
  age={18}
/>

接收:

function Child(props){

  console.log(props)
}

结果:

{
  name:'Rose',
  age:18
}

props 是只读的

React 规定:

props 只能读

不能改

错误写法:

props.name = 'Tom'

原因:

数据由父组件管理

子组件无权修改

遵循:

单向数据流

二、子传父

场景:

子组件产生数据

父组件需要知道

例如:

点击按钮

↓

把数据传给父组件

实现原理

React 中:

函数也可以传递

所以:

父组件传函数

子组件调用函数

通过参数传值

示例

父组件:

import Child from './Child'

function App(){

  const getData = (data)=>{

    console.log(data)

  }

  return (
    <Child getData={getData}/>
  )
}

子组件:

function Child(props){

  const sendData = ()=>{

    props.getData('Hello React')

  }

  return (
    <button onClick={sendData}>
      点击
    </button>
  )
}

输出:

Hello React

子传父流程

父组件

创建函数

↓

传给子组件

↓

子组件调用函数

↓

传递数据

↓

父组件接收

记忆口诀:

父传函数

子调函数

参数传值

什么是状态提升(Lifting State Up)?

当多个组件需要共享同一份数据时,就会涉及:

状态提升

很多人第一次学习时容易理解成:

把数据传给父组件

其实这并不准确。

状态提升真正提升的不是数据,而是:

状态(State)的所有权

可以理解为:

把状态

以及

修改状态的权限

交给共同的父组件统一管理。

例如:

Child1

拥有 count

后来发现:

Child2

也需要 count

这时候,就不应该让 Child1 保存这份状态,而应该把它放到它们共同的父组件中:

Parent

↓

Child1

Child2

此时:

Parent

保存 State

再:

Parent

↓

通过 props

↓

传给 Child1

同时:

Parent

↓

通过 props

↓

传给 Child2

如果 Child1 想修改数据,也不能直接修改,而是:

Child1

↓

调用 Parent 传下来的函数

↓

Parent 更新 State

↓

重新传给两个子组件

整个过程如下:

Child1

↓

通知 Parent

↓

Parent 更新 State

↓

重新渲染

↓

Child1

Child2

所以,可以一句话记住状态提升:

状态提升的本质就是:

把"状态(数据 + 修改权限)"

从某个子组件手里

交给它们共同的父组件统一管理。

这样做最大的好处是:

数据只有一份

不会出现多个组件维护同一份数据

保证数据始终一致。

三、兄弟组件通信

场景:

Child1

↓

Child2

两个组件互相传值。

例如:

购物车组件

↓

商品列表组件

React 中兄弟组件不能直接通信

错误理解:

Child1
 ↓
Child2

React 不支持这样直接传递。

必须经过:

Child1

↓

Parent

↓

Child2

实现方式

例如:

子组件1

传值给父组件

↓

父组件保存数据

↓

传给子组件2

流程:

Child1

↓

Parent

↓

Child2

这也是:

状态提升(Lifting State Up)

思想。


示例

Child1

点击按钮

↓

通知Parent

↓

Parent更新状态

↓

传给Child2

为什么需要状态提升?

React 遵循:

单向数据流(One-Way Data Flow

也就是说:

数据只能:

父组件

↓

子组件

不能直接:

Child1

↓

Child2

所以,当多个组件需要共享同一份数据时,就应该:

把状态放到

它们最近的共同父组件

再由父组件统一:

保存状态

↓

修改状态

↓

传递状态

这就是:

状态提升(Lifting State Up)

也是 React 中最经典、最重要的设计思想之一。

四、仓库思想

当项目变大时:

Header

Sidebar

UserCenter

ProductList

Cart

...

如果一直:

父传子

子传父

会出现:

层层传递

代码混乱

所以需要:

统一数据中心

也就是:

仓库(Store)

后面会学习:

Redux

Zustand

MobX

本质都是:

集中管理状态

五、跨组件通信

场景:

App

↓

AB

↓

C

↓

D

D 需要使用 App 的数据。

如果使用 props:

App

↓

AB

↓

C

↓

D

层层传递。

这就是:

Props Drilling
属性穿透

Context 解决什么问题?

解决:

跨层级组件通信

例如:

祖先组件

↓

任意后代组件

直接共享数据。


createContext

创建上下文对象:

import { createContext }

const UserContext =
  createContext()

Provider 提供数据

父组件:

<UserContext.Provider
  value={'Rose'}
>
  <Child />
</UserContext.Provider>

作用:

向后代组件共享数据

useContext 获取数据

后代组件:

import {
  useContext
} from 'react'

function Child(){

  const value =
    useContext(UserContext)

  return (
    <h1>{value}</h1>
  )
}

结果:

Rose

Context 通信流程

createContext

↓

Provider

↓

useContext

记忆:

创建

提供

消费

Context 的优点

避免:

props层层传递

例如:

App

↓

AB

↓

C

↓

D

D 可以直接获取:

App中的数据

无需经过:

A

B

C

面试高频题

父传子如何实现?

父组件绑定属性

子组件使用props接收

props 能修改吗?

不能

props是只读的

子传父如何实现?

父组件传函数

子组件调用函数

通过参数传值

兄弟组件如何通信?

状态提升

通过共同父组件

流程:

Child1

↓

Parent

↓

Child2

Context 的作用是什么?

解决跨层级组件通信

避免props层层传递

一张图记忆

组件通信

│

├── 父传子
│       ↓
│      props
│
├── 子传父
│       ↓
│    函数回调
│
├── 兄弟通信
│       ↓
│   状态提升
│
└── 跨组件通信

createContext


Provider


useContext

核心口诀

父传子:

props

props只读

----------------

子传父:

父传函数

子调函数

参数传值

----------------

兄弟通信:

状态提升

Child1

↓

Parent

↓

Child2

----------------

跨组件通信:

createContext

↓

Provider

↓

useContext

相关文章

精彩推荐