React Native技术问题:如何从MainTabNavigator调用Messages的refreshMessages函数
问题描述
我有两个组件:Messages.js和MainTabNavigator.js,代码分别如下:
Messages.js
import React, {useState, useEffect} from 'react'; import { View, Text } from 'react-native'; const Messages = () => { const [messages, setMessages] = useState([]); const refreshMessages = async () => { await getMessages(); }; useEffect(() => { getMessages(); }, []); const getMessages = async () => { ... // fetch messages } return ( <View > // Code and graphics.. </View> ); }; export default Messages;
MainTabNavigator.js
import Messages from '../screens/Messages'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; const Tab = createBottomTabNavigator(); const MainTabNavigator = ({navigation}) => { return ( <Tab.Navigator> <Tab.Screen name="Messages" component={Messages} options={{ tabBarIcon: () => ( <MaterialIcons name="auto-awesome" size={22} /> ), headerRight: () => ( <FontAwesome name="refresh" size={22} onPress={() => { refreshMessages() }} // 我想调用Messages.js里的refreshMessages函数,或者触发useEffect重新渲染组件 /> ), }} /> </Tab.Navigator> ); }; export default MainTabNavigator;
需求:在MainTabNavigator的headerRight按钮点击时,调用Messages.js里的refreshMessages函数,或者触发组件重新渲染以刷新数据。
解决方案
方法1:组件Ref + navigation.setOptions
让Messages组件自己管理headerRight的点击事件,通过Ref挂载刷新方法,再动态设置导航栏选项。
修改Messages.js
import React, {useState, useEffect, useRef, useLayoutEffect} from 'react'; import { View, Text } from 'react-native'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; const Messages = ({navigation}) => { const [messages, setMessages] = useState([]); const refreshRef = useRef(); const refreshMessages = async () => { await getMessages(); }; // 将刷新方法挂载到Ref上 refreshRef.current = refreshMessages; useLayoutEffect(() => { // 动态设置headerRight的点击事件 navigation.setOptions({ headerRight: () => ( <FontAwesome name="refresh" size={22} onPress={() => refreshRef.current()} /> ) }); }, [navigation]); useEffect(() => { getMessages(); }, []); const getMessages = async () => { ... // fetch messages } return ( <View > // Code and graphics.. </View> ); }; export default Messages;
修改MainTabNavigator.js
移除原有的headerRight配置:
import Messages from '../screens/Messages'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; const Tab = createBottomTabNavigator(); const MainTabNavigator = ({navigation}) => { return ( <Tab.Navigator> <Tab.Screen name="Messages" component={Messages} options={{ tabBarIcon: () => ( <MaterialIcons name="auto-awesome" size={22} /> ), // 移除原headerRight配置 }} /> </Tab.Navigator> ); }; export default MainTabNavigator;
方法2:全局状态管理(useContext)
通过上下文管理刷新触发信号,让MainTabNavigator发送信号,Messages监听信号并执行刷新。
1. 创建RefreshContext.js
import React, {createContext, useState, useContext} from 'react'; const RefreshContext = createContext(); export const RefreshProvider = ({children}) => { const [shouldRefresh, setShouldRefresh] = useState(false); const triggerRefresh = () => { setShouldRefresh(prev => !prev); }; return ( <RefreshContext.Provider value={{shouldRefresh, triggerRefresh}}> {children} </RefreshContext.Provider> ); }; export const useRefresh = () => useContext(RefreshContext);
2. 根组件包裹Provider
确保MainTabNavigator在RefreshProvider内部:
import {RefreshProvider} from './RefreshContext'; import MainTabNavigator from './MainTabNavigator'; const App = () => { return ( <RefreshProvider> <MainTabNavigator /> </RefreshProvider> ); };
3. 修改MainTabNavigator.js
调用上下文的触发方法:
import Messages from '../screens/Messages'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import {useRefresh} from '../contexts/RefreshContext'; const Tab = createBottomTabNavigator(); const MainTabNavigator = ({navigation}) => { const {triggerRefresh} = useRefresh(); return ( <Tab.Navigator> <Tab.Screen name="Messages" component={Messages} options={{ tabBarIcon: () => ( <MaterialIcons name="auto-awesome" size={22} /> ), headerRight: () => ( <FontAwesome name="refresh" size={22} onPress={triggerRefresh} /> ), }} /> </Tab.Navigator> ); }; export default MainTabNavigator;
4. 修改Messages.js
监听刷新信号:
import React, {useState, useEffect} from 'react'; import { View, Text } from 'react-native'; import {useRefresh} from '../contexts/RefreshContext'; const Messages = () => { const [messages, setMessages] = useState([]); const {shouldRefresh} = useRefresh(); const refreshMessages = async () => { await getMessages(); }; useEffect(() => { getMessages(); }, []); // 监听刷新信号变化,执行刷新 useEffect(() => { if (shouldRefresh) { refreshMessages(); } }, [shouldRefresh]); const getMessages = async () => { ... // fetch messages } return ( <View > // Code and graphics.. </View> ); }; export default Messages;
方法3:React Navigation自定义事件监听
通过导航器的事件系统,发送自定义刷新事件,Messages组件接收事件后执行刷新。
修改MainTabNavigator.js
import Messages from '../screens/Messages'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; const Tab = createBottomTabNavigator(); const MainTabNavigator = ({navigation}) => { return ( <Tab.Navigator> <Tab.Screen name="Messages" component={Messages} options={{ tabBarIcon: () => ( <MaterialIcons name="auto-awesome" size={22} /> ), headerRight: () => ( <FontAwesome name="refresh" size={22} onPress={() => { // 发送自定义刷新事件 navigation.dispatch({ type: 'REFRESH_MESSAGES' }); }} /> ), }} /> </Tab.Navigator> ); }; export default MainTabNavigator;
修改Messages.js
import React, {useState, useEffect} from 'react'; import { View, Text } from 'react-native'; const Messages = ({navigation}) => { const [messages, setMessages] = useState([]); const refreshMessages = async () => { await getMessages(); }; useEffect(() => { getMessages(); // 添加自定义事件监听 const unsubscribe = navigation.addListener('REFRESH_MESSAGES', () => { refreshMessages(); }); return unsubscribe; // 组件卸载时移除监听 }, []); const getMessages = async () => { ... // fetch messages } return ( <View > // Code and graphics.. </View> ); }; export default Messages;
内容的提问来源于stack exchange,提问作者Vito Marseglia
相关产品推荐
相关产品推荐

