React Native 组件间通信方式详解

React Native 组件间通信方式详解

在 React Native 开发中,组件间通信是核心概念之一。以下是几种主要的组件通信方式及其适用场景:

  1. 简单父子通信:使用 props 和回调函数
  2. 兄弟组件通信:提升状态到共同父组件
  3. 跨多级组件:使用 Context API
  4. 全局状态管理:Redux/MobX
  5. 完全解耦组件:事件总线
  6. 命令式操作:Refs
  7. 页面间通信:路由参数

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>;
}

选择建议

  1. 简单父子通信:使用 props 和回调函数
  2. 兄弟组件通信:提升状态到共同父组件
  3. 跨多级组件:使用 Context API
  4. 全局状态管理:Redux/MobX
  5. 完全解耦组件:事件总线
  6. 命令式操作:Refs
  7. 页面间通信:路由参数

最佳实践

  • 优先考虑最简单的 props 传递方式
  • 避免过度使用 Context,合理划分 Context 范围
  • 对于复杂应用,尽早引入状态管理方案
  • 谨慎使用 Refs,避免破坏 React 的数据流
  • 事件总线适合完全解耦的非父子组件通信
相关推荐
Hilaku13 分钟前
为什么死磕 1px 的团队,用户体验反而更差?
前端·javascript·程序员
陈拉斯42 分钟前
给公司年会写了个大屏抽奖系统:动画在前端跑,凭什么说结果没被改?
javascript
yzy851 小时前
Vue中下载或打开文件的JavaScript方法
前端·javascript·vue
用户298698530141 小时前
在 React 中用 JavaScript 将 Word 转换为文本
前端·javascript·react.js
李少兄3 小时前
深入解析 JavaScript 中的 `document` 对象
javascript
paopaokaka_luck3 小时前
考研政治刷题小程序(AI推荐题目、ECharts数据分析、章节练习与专项训练、模拟考试、错题本与收藏夹、学习打卡与目标管理、题库和组卷维护)
前端·javascript·spring boot·spring·数据分析·echarts
刃神太酷啦3 小时前
前端入门第一课:HTML 基础语法 + 常用标签 + 实战全解
服务器·c语言·前端·javascript·css·c++·html
mldong3 小时前
给流程设计器加国际化,我没引 vue-i18n
前端·javascript·vue.js
开开心心就好9 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
默_笙14 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript