我刚刚添加了抽屉导航器,并将屏幕包裹在createDrawerNavigator()
这些是我目前的路线:
当用户从主页导航到发布时,我传递了一个包含发布数据的参数。
onPress={() => this.props.navigation.navigate('Post', {postData: postData})}
只要用户从发布回到首页,发布的邮件就会被卸载。并在点击另一篇文章时再次使用新数据重新安装。
我的问题是,安装抽屉后,导航回 home 时不会卸载 Post 屏幕,我会得到与第一个相同的道具和屏幕帖子一遍又一遍地打开。
这是我的路线设置:
import React from "react";
import { createDrawerNavigator, createStackNavigator, createAppContainer } from 'react-navigation';
import Home from './screens/Home';
import Post from './screens/Post';
import Settings from './screens/Settings';
import SideBar from './screens/sidebar';
const Drawer = createDrawerNavigator(
{
Home: {screen: Home},
Post: {screen: Post},
Settings: {screen: Settings}
},
{
initialRouteName: "Home",
backBehavior: 'initialRoute',
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props} />,
}
);
const AppNavigator = createStackNavigator(
{
Drawer: {screen: Drawer},
},
{
initialRouteName: "Drawer",
headerMode: "none",
}
);
export default createAppContainer(AppNavigator);
我在做什么错了?
我希望每个帖子屏幕都可以打开,并从首页导航到新屏幕时重新呈现。
答案 0 :(得分:8)
对于使用react-navigation v5的用户。通过使用goBack()
作为抽屉中的屏幕链接,我的组件没有被卸载,这也遇到了同样的问题。经过很少的研究,我发现我们在最新版本的react-navigation中,默认情况下在抽屉导航器的屏幕选项中添加了属性unmountonblur
,其属性为false,这就是为什么不卸载组件的原因。我正在用它来解决我的问题。
这是我的代码
<Drawer.Screen name="ResetLogsStack" component={ResetLogsStack} options={{unmountOnBlur:true}}/>
这是该链接:unmountonblur
答案 1 :(得分:1)
我曾经面对同样的问题。我让屏幕Post
听由react-nativation
here而非componentDidMount
触发的导航焦点事件。
import React from 'react';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';
const Post = () => (
<View>
<NavigationEvents
onWillFocus={payload => console.log('will focus',payload)}
onDidFocus={payload => console.log('did focus',payload)} //
onWillBlur={payload => console.log('will blur',payload)}
onDidBlur={payload => console.log('did blur',payload)}
/>
{/*
Your view code
*/}
</View>
);
使用onDidFocus
,您可以获取导航参数,获取数据和/或更新状态。如果需要,您可以使用onDidBlur
清除屏幕状态。
或者,您也可以像this doc here一样进行命令式编码
顺便说一句,我想知道为什么将Post
和Drawer放在一起?只是在抽屉中有一个可以访问“帖子”页面的链接?
我认为,您应该将Home
和Post
移至新堆栈,并将Home
设置为初始路由。这将确保在导航回到Home
后卸载该帖子。
在下面查看我的示例
const HomeStack = createStackNavigatior({
Home: {screen: Home},
Post: {screen: Post},
}, {
initialRouteName: 'Home',
...
})
const Drawer = createDrawerNavigator(
{
HomeStack
Settings: {screen: Settings}
},
{
initialRouteName: "HomeStack",
backBehavior: 'initialRoute',
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props} />,
}
);
答案 2 :(得分:1)
这是react-navigation
的工作方式,为了解决这个问题,您可以添加侦听器,如下所示:
<NavigationEvents
onDidFocus={payload => { console.log(payload.state.params,'<- this has your new params') }}
/>
OR
this.props.navigation.addListener('didFocus', payload=>{console.log(payload)})
检查this以获得更多信息
答案 3 :(得分:0)
我尝试使用答案中建议的方法,但它们不适用于我的情况。
解决方案:
我尝试用createDrawerNavigator()
翻转createStackNavigator()
,它的工作原理和以前一样完美!
我不必使用react导航事件,像componentWillUnmount
和componentWillMount
这样的常规事件可以很好地工作。
const MainScreens = createStackNavigator(
{
Home: {screen: Home},
Post: {screen: Post},
Settings: {screen: Settings}
},
{
initialRouteName: "Home",
headerMode: "none",
}
);
const AppNavigator = createDrawerNavigator(
{
Main: {screen: MainScreens},
},
{
initialRouteName: "Main",
backBehavior: 'initialRoute',
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props} />,
}
);
export default createAppContainer(AppNavigator);
不确定我所做的事情是否有问题,但到现在为止还可以。
答案 4 :(得分:0)
在将React Navigation从2.14.2更新到3.11.0之后,我为此花费了几个小时。有趣的是,它运行良好,并且升级后的页面没有重新渲染,这导致了错误的语言,而不是页面上的实际数据。 我发现的是问题DrawerNavigator screen shouldn't unmount
因此,我们中的一部分人抱怨为什么不重新渲染屏幕,而另一部分人则抱怨为什么要重新渲染屏幕。第二部分赢得了胜利:)
基本上,解决方案符合预期:听WillFocus事件... 如果您希望每次访问都重新呈现它,只需将其添加到您的组件中即可。
/**
* When using React Navigation Component is not umnounted and instead stored in navigator.
* We need component to be rerendered during each visit to show right info and language
*/
componentDidMount() {
//this.props.navigation will come in every component which is in navigator
focusSubscription = this.props.navigation.addListener(
'willFocus',
payload => {
this.forceUpdate();//Native react function to force rerendering
}
);
this.setState({focusSubscription: focusSubscription});
}
componentWillUnmount() {
this.state.focusSubscription.remove();
}
答案 5 :(得分:0)
我正在使用反应导航几个月。但是将屏幕直接放置到Drawer导航器中会阻止willunmount方法被调用。首先将屏幕放置在堆栈导航器中,然后将其放入抽屉导航器中。
答案 6 :(得分:0)
根据 Muhammad Zain 的回复,如果您使用的是 react navigation v5,您可以直接将选项 unmountOnBlur 传递给 Drawer 屏幕
<块引用>options={{unmountOnBlur:true}}
这就足够了。