画面間の移動にstackNavigator
を使用しています。 2番目のアクティビティのcomponentDidMount()
関数で2つのAPIを呼び出しています。初めてロードすると、正常にロードされます。次に、戻るボタンを押して、最初のアクティビティに戻ります。次に、2番目のアクティビティに再び行くと、APIが呼び出されず、レンダリングエラーが発生します。これに対する解決策を見つけることができません。任意の提案をいただければ幸いです。
2019年にここに来る人がいれば、これを試してください:
import {NavigationEvents} from 'react-navigation';
コンポーネントをレンダーに追加します。
<NavigationEvents onDidFocus={() => console.log('I am triggered')} />
これで、このonDidFocusイベントは、goBack()またはナビゲートから来たにもかかわらずページがフォーカスされるたびにトリガーされます。
NavigationEventsコンポーネントを使用する賛成の構文が機能しない場合は、次の方法で試すことができます。
// no need to import anything more
// define a separate function to get triggered on focus
onFocusFunction = () => {
// do some stuff on every screen focus
}
// add a focus listener onDidMount
async componentDidMount () {
this.focusListener = this.props.navigation.addListener('didFocus', () => {
this.onFocusFunction()
})
}
// and don't forget to remove the listener
componentWillUnmount () {
this.focusListener.remove()
}
React-navigationは、画面間を移動してもコンポーネントをマウントしたままにします。コンポーネントを使用して、これらのイベントに対応できます。
<NavigationEvents
onDidFocus={() => console.log('hello world')}
/>
このコンポーネントの詳細 ここ 。
React-navigationのドキュメント この場合は明示的に説明 :
画面AとBを備えたスタックナビゲーターについて考えてみます。 Bをプッシュすると、そのcomponentDidMountも呼び出されますが、Aはスタックにマウントされたままなので、そのcomponentWillUnmountは呼び出されません。
BからAに戻ると、BのcomponentWillUnmountが呼び出されますが、Aはずっとマウントされたままであるため、AのcomponentDidMountは呼び出されません。
現在、そのための3つのソリューションがあります。
ライフサイクルイベントのサブスクライブ
...
React Navigationは、サブスクライブするコンポーネントを選別するイベントを発行します。サブスクライブできる4つの異なるイベントがあります:
willFocus
、willBlur
、didFocus
およびdidBlur
。詳細については、APIリファレンスをご覧ください。ユースケースの多くは、
withNavigationFocus
高次コンポーネント、_<NavigationEvents />
_コンポーネント、またはuseFocusState
フックでカバーできます。
withNavigationFocus
higher-order-component
_import React from 'react';
import { Text } from 'react-native';
import { withNavigationFocus } from 'react-navigation';
class FocusStateLabel extends React.Component {
render() {
return <Text>{this.props.isFocused ? 'Focused' : 'Not focused'}</Text>;
}
}
// withNavigationFocus returns a component that wraps FocusStateLabel and passes
// in the navigation prop
export default withNavigationFocus(FocusStateLabel);
_
_<NavigationEvents />
_コンポーネント
_import React from 'react';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';
const MyScreen = () => (
<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>
);
export default MyScreen;
_
useFocusStateフック
最初にライブラリをインストール_yarn add react-navigation-hooks
_
_import { useNavigation, useNavigationParam, ... } from 'react-navigation-hooks'
function MyScreen() { const focusState = useFocusState(); return <Text>{focusState.isFocused ? 'Focused' : 'Not Focused'}</Text>; }
_
これが私の個人的な解決策です。onDidFocus()
とonWillFocus()
を使用して、APIからデータがフェッチされたときにのみレンダリングします。
_import React, { PureComponent } from "react";
import { View } from "react-native";
import { NavigationEvents } from "react-navigation";
class MyScreen extends PureComponent {
state = {
loading: true
};
componentDidMount() {
this._doApiCall();
}
_doApiCall = () => {
myApiCall().then(() => {
/* Do whatever you need */
}).finally(() => this.setState({loading: false}));
};
render() {
return (
<View>
<NavigationEvents
onDidFocus={this._doApiCall}
onWillFocus={() => this.setState({loading: true})}
/>
{!this.state.loading && /*
Your view code
*/}
</View>
);
}
}
export default MyScreen;
_
Reactでは、componentDidMountは、コンポーネントがマウントされている場合にのみ呼び出されます。親画面で次のようにナビゲートを呼び出すときに、コールバック関数をパラメーターとして渡すことができます。
navigate("Screen", {
onNavigateBack: this.handleOnNavigateBack
});
handleOnNavigateBack = () => {//do something};
そしてチャイルドスクリーン
this.props.navigation.state.params.onNavigateBack();
this.props.navigation.goBack();
drawernavigator
またはstacknavigator
を使用してコンポーネントに移動するたびに何かを実行したい。このため、NavigationEvents
はcomponentDidMount
よりも適しています。
import {NavigationEvents} from "react-navigation";
<NavigationEvents onDidFocus={()=>alert("Hello, I'm focused!")} />
注:ドロワーナビゲーションまたはスタックナビゲーションを使用してコンポーネントにフォーカスした後、NavigationEvents
を使用して毎回タスクを実行する場合より良いアイデアです。ただし、タスクを一度実行する場合は、componenetDidMount
を使用する必要があります。