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 的数据流
  • 事件总线适合完全解耦的非父子组件通信
相关推荐
专业抄代码选手6 小时前
08|Fiber 上的 `useState`:状态终于属于具体组件
前端·javascript·react.js
默_笙6 小时前
😭 Vibe Coding 翻车实录:AI 编程为什么必须先写"剧本"
前端·javascript
lerhxx7 小时前
我用 R3F 手搓了一个能走进去的 3D 迷宫简历(上):从选型架构到迷宫生成算法
前端·javascript·three.js
杉氧12 小时前
状态管理变迁史:为什么我们放弃了 Redux 选择 Zustand?
android·前端·react native
鹏多多12 小时前
PC 网站接入微信登录,这 10 个坑我替你踩完了!
前端·javascript·vue.js
BreezeJiang13 小时前
为什么生成了 dist,项目还是可能跑不起来?从一个 React + Express + MySQL 项目看部署闭环
nginx·react.js
奴心13 小时前
我受够了 value / defaultValue / onChange 三连——一个 prop 重构 React 受控组件
react.js
用户2986985301413 小时前
React 中 HTML 内容转 Word 文档的实现方案
javascript·react.js·html
mONESY13 小时前
我用 Next.js 16 + Supabase 从零做了个「背单词」H5 应用
javascript
boooooooom13 小时前
手把手做一个图 RAG 烹饪问答系统:Neo4j + Milvus + LLM 的工程实践
前端·javascript·后端