第三章:React 进阶
组件通信
在 React 应用中,组件之间的通信是构建复杂功能的核心。根据组件之间的关系(父子、兄弟、跨层级),通信方式也有所不同。以下是常见的组件通信方法:
1. 父子组件通信
父组件向子组件传递数据(Props)
// 父组件
function Parent() {
const message = "Hello from Parent";
return <Child message={message} />;
}
// 子组件
function Child({ message }) {
return <p>{message}</p>; // 输出: Hello from Parent
}
子组件向父组件传递数据(回调函数)
// 父组件
function Parent() {
const handleChildClick = (data) => {
console.log(data); // 输出: Button clicked in Child
};
return <Child onClick={handleChildClick} />;
}
// 子组件
function Child({ onClick }) {
return <button onClick={() => onClick("Button clicked in Child")}>Click</button>;
}
2. 兄弟组件通信
通过共同的父组件(状态提升)
function Parent() {
const [sharedState, setSharedState] = useState("");
return (
<>
<SiblingA setState={setSharedState} />
<SiblingB state={sharedState} />
</>
);
}
3. 跨层级组件通信
Context API
// 创建 Context
const MyContext = createContext();
// 提供者组件
function App() {
const [value, setValue] = useState("Default Value");
return (
<MyContext.Provider value={{ value, setValue }}>
<ComponentA />
</MyContext.Provider>
);
}
// 消费者组件(任意层级)
function ComponentA() {
const { value, setValue } = useContext(MyContext);
return <button onClick={() => setValue("New Value")}>{value}</button>;
}
状态管理库(Redux/Zustand)
// 使用 Zustand 示例
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
function ComponentA() {
const { count, increment } = useStore();
return <button onClick={increment}>{count}</button>;
}
function ComponentB() {
const { count } = useStore();
return <p>Current count: {count}</p>;
}
4. 其他通信方式
事件总线(小型项目适用)
// 创建事件总线
const EventBus = {
events: {},
emit(event, data) {
if (this.events[event]) this.events[event].forEach(fn => fn(data));
},
on(event, callback) {
this.events[event] = this.events[event] || [];
this.events[event].push(callback);
}
};
// 组件A
EventBus.emit("customEvent", { data: 123 });
// 组件B
EventBus.on("customEvent", (data) => console.log(data));
最佳实践建议
- 优先使用 Props 和回调函数处理父子通信
- 对于深层嵌套组件,考虑 Context API
- 全局复杂状态使用状态管理库
- 避免过度使用事件总线(可能导致难以维护)
常见问题解决
- Prop Drilling 问题:当中间组件不需要某些 props 时,考虑使用 Context 或状态管理
- 性能优化:对频繁更新的 Context 值进行拆分,或使用 memoization 技术
