React Native 组件间通信方式详解
在 React Native 开发中,组件间通信是核心概念之一。以下是几种主要的组件通信方式及其适用场景:
- 简单父子通信:使用 props 和回调函数
- 兄弟组件通信:提升状态到共同父组件
- 跨多级组件:使用 Context API
- 全局状态管理:Redux/MobX
- 完全解耦组件:事件总线
- 命令式操作:Refs
- 页面间通信:路由参数
1. 父组件向子组件通信(Props 向下传递)
最基本的通信方式,通过 props 传递数据和回调函数。
jsx
// 父组件
function ParentComponent() {
const [message, setMessage] = useState('Hello from Parent');
return <ChildComponent greeting={message} />;
}
// 子组件
function ChildComponent({greeting}) {
return <Text>{greeting}</Text>;
}
特点:
- 单向数据流
- 简单直接
- 适用于层级不深的组件结构
2. 子组件向父组件通信(回调函数)
通过 props 传递回调函数,子组件调用该函数与父组件通信。
jsx
// 父组件
function ParentComponent() {
const handleChildEvent = (data) => {
console.log('Data from child:', data);
};
return <ChildComponent onEvent={handleChildEvent} />;
}
// 子组件
function ChildComponent({onEvent}) {
return (
<Button
title="Send to Parent"
onPress={() => onEvent('Child data')}
/>
);
}
3. 兄弟组件通信(通过共同父组件)
jsx
function Parent() {
const [sharedData, setSharedData] = useState('');
return (
<>
<SiblingA onUpdate={setSharedData} />
<SiblingB data={sharedData} />
</>
);
}
function SiblingA({onUpdate}) {
return <Button title="Update" onPress={() => onUpdate('New data')} />;
}
function SiblingB({data}) {
return <Text>{data}</Text>;
}
4. Context API(跨层级通信)
适用于深层嵌套组件或全局状态共享。
jsx
const MyContext = React.createContext();
function App() {
const [value, setValue] = useState('Default');
return (
<MyContext.Provider value={{value, setValue}}>
<ParentComponent />
</MyContext.Provider>
);
}
function ChildComponent() {
const {value, setValue} = useContext(MyContext);
return (
<Button
title="Change Value"
onPress={() => setValue('Updated')}
/>
);
}
5. 事件总线(Event Emitter)
适用于完全解耦的组件通信。
jsx
// 创建事件总线
const EventBus = new NativeEventEmitter();
// 发送端组件
function Publisher() {
const emitEvent = () => {
EventBus.emit('customEvent', {data: 'Event data'});
};
return <Button title="Emit Event" onPress={emitEvent} />;
}
// 接收端组件
function Subscriber() {
const [message, setMessage] = useState('');
useEffect(() => {
const subscription = EventBus.addListener('customEvent', (event) => {
setMessage(event.data);
});
return () => subscription.remove();
}, []);
return <Text>{message}</Text>;
}
6. Redux 或 MobX(状态管理库)
适用于大型应用中的复杂状态管理。
jsx
// Redux 示例
import { useSelector, useDispatch } from 'react-redux';
function ComponentA() {
const dispatch = useDispatch();
const updateData = () => {
dispatch({ type: 'UPDATE', payload: 'New data' });
};
return <Button title="Update Store" onPress={updateData} />;
}
function ComponentB() {
const data = useSelector(state => state.data);
return <Text>{data}</Text>;
}
7. Refs(访问组件实例)
用于命令式地访问子组件。
jsx
function ParentComponent() {
const childRef = useRef(null);
const callChildMethod = () => {
childRef.current.doSomething();
};
return (
<>
<ChildComponent ref={childRef} />
<Button title="Call Child Method" onPress={callChildMethod} />
</>
);
}
// 需要使用 forwardRef
const ChildComponent = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
doSomething: () => {
console.log('Method called from parent');
}
}));
return <Text>Child Component</Text>;
});
8. 路由参数(页面间通信)
使用 React Navigation 等路由库传递参数。
jsx
// 发送页面
function HomeScreen({ navigation }) {
return (
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', { itemId: 86 })}
/>
);
}
// 接收页面
function DetailsScreen({ route }) {
const { itemId } = route.params;
return <Text>Item ID: {itemId}</Text>;
}
选择建议
- 简单父子通信:使用 props 和回调函数
- 兄弟组件通信:提升状态到共同父组件
- 跨多级组件:使用 Context API
- 全局状态管理:Redux/MobX
- 完全解耦组件:事件总线
- 命令式操作:Refs
- 页面间通信:路由参数
最佳实践
- 优先考虑最简单的 props 传递方式
- 避免过度使用 Context,合理划分 Context 范围
- 对于复杂应用,尽早引入状态管理方案
- 谨慎使用 Refs,避免破坏 React 的数据流
- 事件总线适合完全解耦的非父子组件通信