目录
3. 兄弟组件:状态提升(Lifting State Up)
引言
“在 React 开发中,组件之间的数据传递就像现实中的聊天——父子组件可以直接对话,兄弟组件需要‘中介’,而跨层级组件可能得靠‘广播’。今天,我就结合 6 年实战经验,带大家解锁 React 组件通信的 6 种姿势,让你彻底告别‘数据孤岛’!”
1. 父子组件:props 直传(最基础)
场景:父组件向子组件传递数据或函数。
// 父组件
const Parent = () => {
const [message, setMessage] = useState("Hello from Parent!");
return <Child greeting={message} />;
};
// 子组件
const Child = ({ greeting }) => {
return <h1>{greeting}</h1>; // 直接使用父组件传递的 props
};
我的吐槽:
“这就像老爸直接给儿子零花钱,简单粗暴,但儿子没法主动要钱(子组件不能反向传数据)。”
2. 子传父:回调函数(Callback)
场景:子组件通过父组件传递的函数“逆向”通信。
// 父组件
const Parent = () => {
const handleChildClick = (data) => {
console.log("子组件说:", data); // 接收子组件数据
};
return <Child onClick={handleChildClick} />;
};
// 子组件
const Child = ({ onClick }) => {
return <button onClick={() => onClick("I'm Child!")}>点我传数据</button>;
};
我的心得:
“这种方式适合简单的交互,比如表单提交。但如果层级太深,props 会变成‘击鼓传花’,代码容易变乱。”
3. 兄弟组件:状态提升(Lifting State Up)
场景:两个兄弟组件共享父组件的状态。
// 父组件
const Parent = () => {
const [count, setCount] = useState(0);
return (
<>
<SiblingA count={count} />
<SiblingB onUpdate={() => setCount(count + 1)} />
</>
);
};
// 兄弟组件 A(显示数据)
const SiblingA = ({ count }) => <div>当前计数:{count}</div>;
// 兄弟组件 B(修改数据)
const SiblingB = ({ onUpdate }) => <button onClick={onUpdate}>+1</button>;
我的比喻:
“这就像两兄弟共用老爸的支付宝账号——花钱(SiblingB)和查余额(SiblingA)都得通过老爸(Parent)。”
4. 跨层级组件:Context API
场景:避免多层 props 透传,实现“隔代通信”。
// 创建 Context
const ThemeContext = createContext("light");
// 祖父组件
const Grandparent = () => {
return (
<ThemeContext.Provider value="dark">
<Parent />
</ThemeContext.Provider>
);
};
// 孙子组件(跳过 Parent)
const Grandchild = () => {
const theme = useContext(ThemeContext);
return <div>当前主题:{theme}</div>; // 直接拿到祖父的数据
};
我的提醒:
“Context 适合全局主题、用户信息等低频更新数据。频繁更新的值用 Context 可能导致性能问题!”
5. 任意组件:事件总线(Event Bus)
场景:完全不相关的组件间通信,类似“广播”。
// 事件总线(可以用 mitt 或自定义)
const eventBus = new EventEmitter();
// 组件 A(发布事件)
const ComponentA = () => {
const emitEvent = () => eventBus.emit("alert", "我是组件A发的消息!");
return <button onClick={emitEvent}>发布事件</button>;
};
// 组件 B(订阅事件)
const ComponentB = () => {
const [message, setMessage] = useState("");
useEffect(() => {
eventBus.on("alert", setMessage);
return () => eventBus.off("alert", setMessage);
}, []);
return <div>收到消息:{message}</div>;
};
我的警告:
“事件总线虽然灵活,但容易导致代码难以维护。慎用,除非你真的需要‘广播’!”
6. 全局状态管理:Redux / Zustand
场景:复杂应用需要集中管理状态。
// 以 Zustand 为例
import { create } from "zustand";
// 创建 store
const useStore = create((set) => ({
user: null,
login: (name) => set({ user: name }),
}));
// 组件 A(修改状态)
const ComponentA = () => {
const login = useStore((state) => state.login);
return <button onClick={() => login("小杨")}>登录</button>;
};
// 组件 B(读取状态)
const ComponentB = () => {
const user = useStore((state) => state.user);
return <div>当前用户:{user || "未登录"}</div>;
};
我的选择:
“Redux 适合大型项目,但学习成本高。个人更推荐 Zustand,API 简单,够用!”
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:
906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!