监听关闭事件反应导航
Posted
技术标签:
【中文标题】监听关闭事件反应导航【英文标题】:Listen for dismiss event react navigation 【发布时间】:2020-12-27 17:40:43 【问题描述】:我在反应导航中有一个模态,写成一个功能组件。在 ios 上,只需向下滑动即可将其关闭。所以我没有后退按钮或任何东西。
我希望能够监听模态框上的关闭事件,因此我可以调用一个函数来清除(redux)状态并在模态框关闭时获取新数据。
navigation.addListener('willBlur')
事件不起作用,因为当我从该模式打开另一个模式时也会触发该事件。
useEffect 看起来很有希望,但我无法让它发挥作用。每次依赖变化时,都会运行效果清理。
const filters = useSelector(taskFilters);
const dispatch = useDispatch();
const isFirstRun = useRef(true);
useEffect(() =>
// Skip first render
if (isFirstRun.current)
isFirstRun.current = false;
return;
// effect cleanup
return () =>
dispatch(cleanUpAndFetch(filters));
;
, [filters]);
如果我这样做,它只会在组件卸载时被调用。但是现在我有一个旧版本的过滤器,因为它们不是作为依赖项提供的。如果数据已更改,我只想调用 cleanUpAndFetch,所以我仍然需要处理这个问题
useEffect(() =>
return () =>
dispatch(cleanUpAndFetch(filters));
;
, []);
总结一下。有没有办法?
我使用最新版本的 Expo 和 React Navigation v.4
编辑:
模态是通过导航配置创建的,如下所示:
export const RootStack = createStackNavigator(
Main:
screen: RootSwitchStack,
navigationOptions:
headerShown: false,
headerBackTitleVisible: false
,
MyModal,
ChildModal // Gets opened from MyModal
,
initialRouteName: 'Main',
mode: 'modal',
defaultNavigationOptions:
...headerSetup,
...modalTransitions
);
MyModal
是我需要类似onRequestClose
的地方
【问题讨论】:
【参考方案1】:我仍在寻找解决方案,但我已经实施了以下解决方法:
IOS modal 将使用默认转换,只能使用标题返回按钮关闭。
import
createStackNavigator,
TransitionPresets
from 'react-navigation-stack';
...
export const RootStack = createStackNavigator(
Main:
screen: RootSwitchStack,
navigationOptions:
headerShown: false,
headerBackTitleVisible: false
,
MyModal:
screen: MyModal,
navigationOptions: (navigation) => (
// Our previous were ModalPresentationIOS, but we cannot know
// when the component has been dismissed, so we use a modal with
// back button
...TransitionPresets.DefaultTransition,
headerLeft: () => <HeaderBack navigation=navigation />
)
,
ChildModal // Gets opened from MyModal
,
initialRouteName: 'Main',
mode: 'modal',
defaultNavigationOptions:
...headerSetup,
...modalTransitions
);
import HeaderBackButton from 'react-navigation-stack';
export const HeaderBack = (
navigation
:
navigation: NavigationStackProp;
) =>
const filters = useSelector(taskFilters);
const [initialFilters] = useState(filters);
const dispatch = useDispatch();
// We use a bit more complex comparison, but geist of it is the same
const isFiltersTheSameAsInitial = initialFilters === filters;
return (
<HeaderBackButton
labelVisible=false
onPress=() =>
if (!isFiltersTheSameAsInitial)
dispatch(cleanUpAndFetch(filters));
navigation.pop();
tintColor=colors.black
/>
);
;
【讨论】:
【参考方案2】:iOS 中的 'Dismiss' 事件可以由 5.x 版本中的 beforeRemove
导航事件/监听器处理(不确定它是否在 4.x 中可用)。
查看这些文档:https://reactnavigation.org/docs/navigation-events/
您可以通过多种方式收听此事件,但这里是一个示例:
screenListeners =
focus: () =>
// do something when screen opens & is focused
,
beforeRemove: () =>
// do something when scree is closed OR dismissed (in iOS)
;
以及稍后渲染时...
<RootStack.Navigator mode="modal">
<RootStack.Screen
name="MyScreen"
component=MyScreenStackNavigator
listeners=screenListeners
/>
</RootStack.Navigator>
文档中的其他示例:https://reactnavigation.org/docs/navigation-events/#listeners-prop-on-screen
【讨论】:
太棒了!当我们升级到 5.0+ 时会试用它以上是关于监听关闭事件反应导航的主要内容,如果未能解决你的问题,请参考以下文章