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 的数据流
  • 事件总线适合完全解耦的非父子组件通信
相关推荐
橘子星2 分钟前
树与二叉树:从概念到 JavaScript 实现
前端·javascript·面试
小林ixn13 分钟前
前端开发新利器:用Vite+通义万相实现多模态图像生成(附API密钥安全方案)
javascript
用户9385156350716 分钟前
HTML5 Canvas 从入门到AI驱动游戏开发:手把手教你用原生JS打造飞机游戏与数据可视化
前端·javascript·人工智能
weedsfly19 分钟前
React 开发中的闭包陷阱:四个真实场景,让你彻底理解闭包
前端·react.js
qq_4221525736 分钟前
视频转 GIF 工具怎么选?2026 年动图制作方案与画质参数对比
javascript·vue.js·音视频
怕浪猫1 小时前
Electron 开发实战(十五):实战项目|从零搭建桌面即时通讯(IM)应用
前端·javascript·electron
2501_912784081 小时前
跨境电商独立站技术选型:为什么React+Vue+Laravel成为主流?
vue.js·react.js·laravel·taocarts
不吃鱼的羊1 小时前
DaVinci配置NVM模块
前端·javascript·网络
一坨阿亮1 小时前
使用e-tree开发树形穿梭框
javascript·vue.js·elementui