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 的数据流
  • 事件总线适合完全解耦的非父子组件通信
相关推荐
dly_blog42 分钟前
setup 函数完整指南!
前端·javascript·vue.js
写代码的jiang1 小时前
【无标题】实战:Vue3 + Element Plus 实现树形选择器全量预加载与层级控制
前端·javascript·vue.js
晚烛1 小时前
实战前瞻:构建高可靠、低延迟的 Flutter + OpenHarmony 智慧交通出行平台
前端·javascript·flutter
WHOVENLY2 小时前
【javaScript】- 作用域[[scope]]
前端·javascript
来杯三花豆奶2 小时前
Vue3 Pinia 从入门到精通
前端·javascript·vue.js
syt_10132 小时前
设计模式之-工厂模式
javascript·单例模式·设计模式
weibkreuz2 小时前
React的基本使用@2
前端·javascript·react.js
于是我说2 小时前
前端JavaScript 项目中 获取当前页面滚动位置
开发语言·前端·javascript
小肖爱笑不爱笑2 小时前
JavaScript
java·javascript·json·web
凯小默2 小时前
02.内存管理和内存泄漏
javascript