mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1156 字
3 分钟
React组件通信
2026-05-03
无标签

Alt text

组件通信的官方定义#

在React中,组件通信指的是不同React组件之间进行数据、事件或状态交互的过程。

React的组件化架构下,组件作为独立的功能单元,根据组件间的层级关系(父子、兄弟、跨层级/全局),遵循单向数据流核心原则(数据自顶向下传递,状态变更自下而上通知)实现信息传递,是构建复杂React应用的核心基础能力之一。

组件通信的核心作用#

  1. 状态共享与同步:让多个组件能访问和同步相同的业务数据(如用户信息、表单状态),保证应用状态的一致性;
  2. 交互联动:实现组件间的行为触发(如子组件点击按钮通知父组件更新数据、兄弟组件间的操作联动);
  3. 解耦与复用:通过标准化的通信方式,让组件保持独立封装性,同时能灵活组合复用,降低组件间的耦合度;
  4. 全局状态管理:支撑大型应用中跨层级、跨模块组件的状态统一管理,提升应用可维护性。

组件通信的使用方法#

1. 父子组件通信(最基础)#

父传子:Props 传递#

父组件通过属性(props)向子组件传递数据/方法,子组件通过定义TypeScript类型接收并使用。

// 子组件
interface ChildProps {
userName: string;
onNameChange: (name: string) => void;
}
const Child: React.FC<ChildProps> = ({ userName, onNameChange }) => {
return (
<div>
<p>用户名:{userName}</p>
<button onClick={() => onNameChange("新用户名")}>修改名称</button>
</div>
);
};
// 父组件
const Parent: React.FC = () => {
const [name, setName] = React.useState("初始用户名");
return <Child userName={name} onNameChange={setName} />;
};

子传父:回调函数#

子组件调用父组件通过props传入的回调函数,将子组件的状态/数据传递给父组件(如上例中onNameChange)。

2. 兄弟组件通信#

通过共同的父组件作为“中间层”:

  1. 父组件管理共享状态和修改状态的方法;
  2. 父组件将状态传递给兄弟A,将修改方法传递给兄弟B;
  3. 兄弟B调用方法修改状态,父组件更新后传递给兄弟A,实现联动。

3. 跨层级/深层级组件通信#

Context API#

适用于多层级组件共享数据,避免props逐级传递(props drilling):

// 创建Context
interface UserContextType {
userId: number;
updateUserId: (id: number) => void;
}
const UserContext = React.createContext<UserContextType | undefined>(undefined);
// 父组件(Provider)
const App: React.FC = () => {
const [userId, setUserId] = React.useState(1);
const updateUserId = (id: number) => setUserId(id);
return (
<UserContext.Provider value={{ userId, updateUserId }}>
<DeepChild />
</UserContext.Provider>
);
};
// 深层子组件(Consumer)
const DeepChild: React.FC = () => {
const context = React.useContext(UserContext);
if (!context) throw new Error("必须在UserContext.Provider中使用");
return (
<div>
<p>用户ID:{context.userId}</p>
<button onClick={() => context.updateUserId(2)}>修改ID</button>
</div>
);
};

Redux/Zustand(全局状态管理)#

适用于大型应用的全局组件通信:

  • Redux:基于单向数据流,通过Action、Reducer、Store管理全局状态,组件通过useSelector获取状态,useDispatch触发状态修改;
  • Zustand:轻量级状态管理库,简化Redux的繁琐配置,通过创建store直接在组件中调用。

4. 非关联组件通信#

事件总线(Event Bus)#

适用于小型场景,通过自定义事件发布/订阅实现:

// 简易事件总线
class EventBus {
private events: Record<string, Array<(...args: any[]) => void>> = {};
on(event: string, callback: (...args: any[]) => void) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
emit(event: string, ...args: any[]) {
this.events[event]?.forEach(callback => callback(...args));
}
}
// 全局实例
const eventBus = new EventBus();
// 组件A发布事件
const ComponentA: React.FC = () => {
return <button onClick={() => eventBus.emit("dataChange", "新数据")}>发送数据</button>;
};
// 组件B订阅事件
const ComponentB: React.FC = () => {
const [data, setData] = React.useState("");
React.useEffect(() => {
eventBus.on("dataChange", (newData) => setData(newData));
// 清理订阅
return () => {
eventBus.events.dataChange = [];
};
}, []);
return <p>接收的数据:{data}</p>;
};

组件通信的使用案例#

案例1:表单组件与父组件通信(父子通信)#

// 表单子组件
interface LoginFormProps {
onSubmit: (formData: { username: string; password: string }) => void;
}
const LoginForm: React.FC<LoginFormProps> = ({ onSubmit }) => {
const [username, setUsername] = React.useState("");
const [password, setPassword] = React.useState("");
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit({ username, password });
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="用户名"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="密码"
/>
<button type="submit">登录</button>
</form>
);
};
// 父组件
const LoginPage: React.FC = () => {
const handleFormSubmit = (formData: { username: string; password: string }) => {
console.log("提交的表单数据:", formData);
// 调用登录接口等逻辑
};
return <LoginForm onSubmit={handleFormSubmit} />;
};

案例2:全局主题切换(Context API)#

// 主题Context
type Theme = "light" | "dark";
interface ThemeContextType {
theme: Theme;
toggleTheme: () => void;
}
const ThemeContext = React.createContext<ThemeContextType | undefined>(undefined);
// 主题Provider
const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [theme, setTheme] = React.useState<Theme>("light");
const toggleTheme = () => setTheme(prev => prev === "light" ? "dark" : "light");
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// 头部组件(使用主题)
const Header: React.FC = () => {
const context = React.useContext(ThemeContext);
if (!context) throw new Error("需在ThemeProvider中使用");
return (
<header style={{ background: context.theme === "light" ? "#fff" : "#333", color: context.theme === "light" ? "#333" : "#fff" }}>
<button onClick={context.toggleTheme}>切换主题</button>
<h1>当前主题:{context.theme}</h1>
</header>
);
};
// 应用入口
const App: React.FC = () => {
return (
<ThemeProvider>
<Header />
<main style={{ background: React.useContext(ThemeContext)?.theme === "light" ? "#f5f5f5" : "#222" }}>
应用内容
</main>
</ThemeProvider>
);
};

组件通信的使用注意事项#

  1. Props 只读性:子组件永远不要修改父组件传递的props,如需修改需通过回调函数通知父组件更新,遵循React单向数据流原则;
  2. Context API 慎用场景:Context的每次value更新都会导致所有消费该Context的组件重新渲染,避免将频繁变化的数据放入Context,可拆分多个Context减少不必要的重渲染;
  3. 全局状态管理选型:小型应用优先使用Context + useReducer,中型/大型应用可选择Zustand/Redux Toolkit,避免过度设计;
  4. 事件总线清理:使用Event Bus时,需在组件卸载时清理订阅的事件,防止内存泄漏;
  5. TypeScript 类型校验:所有通信传递的props、Context、状态都要定义明确的TypeScript类型,避免类型错误;
  6. 避免过度props drilling:当props需要传递超过2-3层时,优先使用Context或状态管理库,提升代码可维护性;
  7. 性能优化
    • 传递给子组件的回调函数可通过useCallback缓存,避免子组件不必要的重渲染;
    • 传递的对象/数组可通过useMemo缓存,防止因引用变化导致的重渲染;
  8. 跨组件通信优先级:优先使用层级就近的通信方式(父子>兄弟>Context>全局状态),减少全局状态的滥用。
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

React组件通信
https://www.choria.top/posts/props/
作者
乔瑞雅·克林威尔
发布于
2026-05-03
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录