Component Communication in React 18 and Vue 3: Parent‑Child, Sibling, and Cross‑Level Patterns
This article compares React 18 and Vue 3 component communication techniques—including parent‑child, sibling, and cross‑level patterns—provides detailed code examples for props, emit, context, provide/inject, and summarizes their respective advantages and use cases in modern web development.
Introduction
After exploring Vue 3, the author initiates a comparison with React 18 focusing on component communication methods: parent‑child, sibling, and cross‑layer communication.
1. Parent‑Child Communication
React 18
Data is passed from parent to child via props attributes, and the child accesses them through the props object. The reverse direction uses a callback function passed as a prop, which the child invokes to send data back.
function App() {
return (
);
}
function Son1(props) {
return (
姓名:{props.name}
年龄:{props.age}
内容:{props.children}
);
}The special props.children prop contains any nested content inside the component tag.
import React, { useState } from 'react';
function Parent() {
const [msg, setMsg] = useState('');
const handleMsg = (msg) => { setMsg(msg); };
return (
父组件状态:{msg}
);
}
function Son1({ handleMsg }) {
const sonMsg = '我是Son1子组件';
return
handleMsg(sonMsg)}>点击传递消息
;
}Vue 3
Parent components pass data via props , while child components declare received props using defineProps . Methods can be exposed to the parent with defineExpose and accessed via ref or template refs.
<template>
<Son :name="parentName" :age="parentAge" />
</template>
<script setup>
import { ref } from 'vue';
import Son from './Son.vue';
const parentName = ref('李四');
const parentAge = ref(20);
</script> // Son.vue
<script setup>
defineProps({
name: { type: String, required: true },
age: Number
});
</script> // Expose method
<script setup>
import { defineExpose } from 'vue';
defineExpose({
foo() { console.log('这是来自子组件的foo方法'); },
childName: '这是子组件的属性'
});
</script> // Parent uses ref
<template>
<Child ref="cmp" />
<button @click="handleClick">按钮</button>
</template>
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';
const cmp = ref(null);
function handleClick() {
cmp.value.foo();
cmp.value.childName = '修改了子组件的属性';
console.log(cmp.value);
}
</script>2. Cross‑Layer Communication
React
Implemented with the Context API: create a context, wrap components with a Provider , and consume the value using the useContext hook.
import React, { createContext, useContext } from 'react';
const MsgContext = createContext();
function ContextApp() {
const msg = 'this is app';
return (
我是 App 组件
);
}
function A() {
const sonMsg = '我是 son1 子组件';
return (<>{sonMsg}
);
}
function B() {
const msg = useContext(MsgContext);
return
this is B,{msg}
;
}
export default ContextApp;Vue 3
Uses provide in the ancestor and inject in descendants.
<!-- Parent.vue -->
<template>
<div>
<h2>我是 App 组件</h2>
<A />
</div>
</template>
<script setup>
import { provide } from 'vue';
import A from './A.vue';
const msg = 'this is app';
provide('msg', msg);
</script> <!-- B.vue -->
<template>
<div>this is B,{{ msg }}</div>
</template>
<script setup>
import { inject } from 'vue';
const msg = inject('msg');
</script>3. Sibling Communication
React
Achieved by lifting shared state to a common parent and passing callbacks via props.
function Parent() {
const [msg, setMsg] = useState('');
const getMsg = (msg) => setMsg(msg);
return (
父组件状态:{msg}
);
}
function Son1({ getMsg }) {
const sonMsg = '我是Son1子组件';
return
getMsg(sonMsg)}>传递消息
;
}
function Son2({ msg }) {
return
兄弟组件接收到的消息:{msg}
;
}Vue 3
Similarly, the parent passes data via props and children emit events back.
<!-- Parent.vue -->
<template>
<Son1 @sendMessage="receiveMessage" />
<Son2 :msg="message" />
</template>
<script setup>
import { ref } from 'vue';
import Son1 from './Son1.vue';
import Son2 from './Son2.vue';
const message = ref('');
function receiveMessage(msg) { message.value = msg; }
</script> <!-- Son1.vue -->
<template>
<button @click="sendMessage">传递消息</button>
</template>
<script setup>
const emit = defineEmits();
function sendMessage() { emit('sendMessage', '我是Son1子组件'); }
</script> <!-- Son2.vue -->
<template>
<h2>兄弟组件接收到的消息:{{ msg }}</h2>
</template>
<script setup>
defineProps({ msg: String, required: true });
</script>Comparison Table
Feature
React
Vue 3
Cross‑layer method
context&
useContext provide&
injectData flow direction
Providerpasses down,
Consumerreads
providein parent,
injectin descendant
Typical scenario
Medium‑scale apps needing global state
Deeply nested component data sharing
Conclusion
Both React 18 and Vue 3 offer mechanisms to simplify component communication. React relies on the Context API for cross‑layer sharing, while Vue 3 uses provide / inject . Understanding these patterns helps developers choose the appropriate approach for their project's architecture.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.