我一直在使用StackNavigator来实现我的大多数应用程序。现在,我添加了一个DrawerNavigator,从它的一个屏幕调用原始StackNavigator的另一个屏幕。例如,考虑用户可以执行以下导航顺序:
ScreenA -> ScreenB -> ScreenC
其中ScreenA属于StackNavigator,ScreenB属于DrawerNavigator,而ScreenC再次属于StackNavigator。为此,实际上ScreenA并不直接调用ScreenB,而是另一个屏幕,其唯一目的是充当属于DrawerNavigator的所有屏幕的根。另外,该根在ScreenProps中接收StackNavigator,以便其屏幕以后可以再次使用Stack。
现在,如果我在ScreenC中,并且使用“ this.props.navigation.goBack()”返回,我将返回到ScreenB中的DrawerNavigator,因为这就是所谓的ScreenC。 ScreenB应该刷新其状态,也就是说,它应该从数据库中重新加载信息,因为该信息可能已在ScreenC中更改,因此以前的状态不再有效。
仅在使用StackNavigator时,我总是设法使用“ NavigationEvents”来做到这一点。例如:
import {Component} from 'react'
...
import { NavigationEvents } from 'react-navigation'
class ScreenB extends Component{
// This is the function that loads information from the database (PouchDB)
loadInformation = async() =>{
...
}
render(){
return(
<View>
<NavigationEvents onWillFocus = {payload => this.loadInformation()}/>
<NavigationEvents onDidFocus = {payload => this.loadInformation()}/>
...
</View>
)
}
}
通过此实现,功能“ loadInformation”在我第一次进入屏幕时以及从子屏幕返回时都被激活。但是这一次我混用了两个导航器,从ScreenC返回到ScreenB时“ onWillFocus”和“ onDidFocus”都没有激活,因此我无法再次进入“ loadInformation”功能。我该怎么办?
编辑:
我还尝试在Redux存储中保留一个布尔变量,该布尔变量确定是否必须激活ScreenB的功能“ loadInformation”。该变量以真实值开头。然后,一旦我进入屏幕B并执行了该功能,它将更改为false。当我导航至ScreenC时,该屏幕中的变量再次更改为true,因此当我返回至ScreenB时,它再次表明必须执行该函数。
需要在ScreenB中使用“ componentDidUpdate”函数,该函数不断检查该变量是true还是false,以便调用“ loadInformation”。那解决了问题,但带来了一个新问题。当我尝试从ScreenB导航到DrawerNavigator的另一个屏幕时,这会花费太多时间,因为在过渡过程中会反复调用“ componentDidUpdate”。因此,该解决方案似乎不可行。
答案 0 :(得分:0)
很遗憾,您使用的方法<NavigationEvents>
已更新。因此,您应该做的是:
class screenA/ screenB/ screenC extends React.Component {
componentDidMount() {
this._unsubscribe = navigation.addListener('focus', () => {
// do something
});
}
componentWillUnmount() {
this._unsubscribe();
}
render() {
// Content of the component
}
}
在所有屏幕上使用这些更新的导航事件。希望它能解决您的问题。有关更多信息,See This
答案 1 :(得分:0)
我正在回答我自己的问题。
解决方案是使用 Redux 存储中的布尔变量,指示是否必须激活函数“loadInformation”。假设变量名为“loadView”,默认值为“false”,但 ScreenC 在关闭时将其设置为“true”,因此我们将返回 ScreenB。
也就是说,ScreenC的文件中包含如下代码:
import {Component} from 'react'
import { connect } from 'react-redux'
// Here we import the action that allows to change the value of "loadView"
import { changeLoadView } from '../../redux/actions/popUpActions'
...
class ScreenC extends Component{
...
// Function that is activated automatically when we leave the screen
componentWillUnmount(){
// This is the function that assigns the value "true" to "loadView"
this.props.dispatchChangeLoadView(true)
}
...
}
const mapStateToProps = (state) => {
return {
...
}
}
const mapDispatchToProps = (dispatch) => {
return {
dispatchChangeLoadView: (bool) => dispatch(changeLoadView(bool)),
....
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreenC);
在 ScreenB 的文件中,我使用了一个“假视图”,它是一个 React 视图,它没有直接放在“渲染”函数中,而是由另一个函数调用(在这种情况下称为“activateLoadInformation”)。该函数返回一个空视图,但使用它的原因是因为在它“返回”之前,我们可以激活我们想要的 ScreenB 的任何其他函数,在这种情况下是“loadInformation”。我不知道另一种激活函数的方法,这些函数在我们想要的时候不会随意渲染任何东西。
import {Component} from 'react'
import { connect } from 'react-redux'
...
class ScreenB extends Component{
...
// This is the function that loads information from the database (PouchDB)
loadInformation = async() =>{
this.props.dispatchChangeLoadView(false);
...
}
// Fake view that calls the function "loadInformation"
activateLoadInformation(){
this.loadInformation();
return(<View/>)
}
render(){
return(
<View>
{!this.props.loadView &&
<NavigationEvents onWillFocus = {payload => this.loadInformation()}/>
}
{this.props.loadView &&
this.activateLoadInformation()
}
...
</View>
)
}
}
const mapStateToProps = (state) => {
return {
loadView: state.popUpReducer.loadView,
}
}
const mapDispatchToProps = (dispatch) => {
return {
dispatchChangeLoadView: (bool) => dispatch(changeLoadView(bool)),
....
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreenB);