我有两个屏幕:A和B,与StackNavigator连接
屏幕A是QR码扫描仪。扫描QR码后,它立即导航到屏幕B。
在屏幕B中,我使用从屏幕A作为导航参数传递的QR码进行API调用。我在componentDidMount中触发了此API调用。
我的问题是:如果我从A导航到B,然后返回A,然后再次导航到B,则不会调用componentDidMount,并且我无法触发API调用。
这是一些代码
屏幕A
在扫描QR码时调用的处理程序函数:
handleQRCode = qrCode => {
NavigationService.navigate('Decode', {qrCode});
};
屏幕B
QR代码从导航状态参数中提取,并通过redux用于API调用(startDecode)。
componentDidMount() {
qrCode = this.props.navigation.state.params.qrCode;
this.props.startDecode(qrCode.data);
}
我的问题是,componentDidMount仅在首次采用该路由时才被调用。
答案 0 :(得分:1)
在react-navigation
中,每个屏幕都保持安装状态。这意味着当您返回到B时,您可能已经更改了道具,但是componentDidMount
在此屏幕的首次创建中已经被调用。
有两种可供选择的选项(AFAIK)可以处理这种情况:
this.props.navigation.navigate()
this.props.navigation.push
将创建另一个实例
屏幕B,从而调用componentDidMount
React生命周期
事件。getDerivedPropsFromState
,也可以在不久的将来完成
不推荐使用的componentWillReceiveProps
。答案 1 :(得分:1)
我遇到了类似的问题,因此我使用this.props.navigation.addListener()
来解决它。基本上,可以通过再次推动相同的屏幕using a key(我还没有尝试过)来强制调用componentDidMount()
(但您的堆栈也将保持增长,这不是最佳选择)。因此,当您返回到已经在堆栈中的屏幕时,可以使用addListener()
来查看它是否重新聚焦,并且可以在此处复制componentDidMount()
代码:
class MyClass extends Component {
someProcess = () => {
// Code common between componentDidMount() and willFocus()
}
componentDidMount() {
this.someProcess();
}
willFocus = this.props.navigation.addListener(
'willFocus',
(payload) => {
this.someProcess();
}
);
}
第一次调用MyClass
时,将调用componentDidMount
。在其他时候它仍然处于堆栈中但只是获得焦点时,将addListener
被调用。
答案 2 :(得分:0)
之所以发生这种情况,是因为B组件仅在首次访问时才安装,因此不会再次调用componentDidMount。
我建议您通过'didAppear'事件将回调传递给导航器的setOnNavigatorEvent
方法。您的回调将在react-native-navigation发出的每个事件上调用,并且您可以验证每次屏幕出现时都执行逻辑(因此使用'didAppear'事件)。您可以基于以下代码:
export default class ExampleScreen extends Component {
constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
}
onNavigatorEvent(event) {
if (event.id === 'didAppear') {
// do API call here
}
}
}