やったこと
- React NativeでReact Navigationでの画面遷移時に再レンダリングを行なった
問題
- React Navigation Stackで画面遷移(新規レコード作成↔︎一覧ページ)を実施していた
- 作成画面→一覧画面への遷移をnavigation.navigate()で行なったが、新しく作成したレコードが表示されなかった
実装方法
- 再レンダリングするには、propsかstateを変更する必要がある
- 今回はReduxを使用しているので、actionを実行して、propsに変化を与えれば良い
- それをEventListenerとして設定することで、毎回の画面遷移時に行うことができる
本体部分は以下のみ
HomeScreen.js
const { navigation } = this.props;
this.focusListerner = navigation.addListener('didFocus', () => {
this.props.fetchAllReviews();
// fetchAllReviewsはReduxのaction。全てのレコードを取得する
});
}
遷移元は通常通り、this.props.navigation.navigate('home')
しているだけ
AddScreen.js
onAddButtonPress = () => {
// 〜色々な処理〜
this.props.navigation.navigate('home');
}
その他の関数実行方法
React Navigationの公式ページを参照
https://reactnavigation.org/docs/en/function-after-focusing-screen.html
ページ遷移時に関数実行(→結果として再レンダリング)を行う方法は2種類
- 高階コンポーネント
withNavigationFocus
を使用する - 今回の、EventListerを使用して'didMount'をListenする
高階コンポーネントとは
あるコンポーネントを受け取って新規のコンポーネントを返すような関数です
https://ja.reactjs.org/docs/higher-order-components.html
詳しくは調べていないのですが、概要は以下です。
- react-navigationが持つ
isFocused
というpropsは、対象画面がfocusされているかによって、true
かfalse
となる。 - この場合、毎回focusとunfocus時にpropsが変更→再レンダリングが実行されてしまうため、不要に再レンダリングが起きてしまう可能性がある
とのことで、今回focus時にのみ関数を実行したかったため、EventListerを使用する方法をとりました。
よろしければ、試してみてください!
また、React-Native始めたばかりでまだわかっていない部分が多いので、他に良い方法があれば教えてください。
参考に、navigationの設定部分
App.js
render() {
const headerNavigationOptions = {
headerStyle: {
backgroundColor: '#6FB620',
margingTop: (Platform.OS === 'android' ? 24 : 0),
},
headerTitleStyle: { color: 'white' },
headerTintColor: 'white',
};
const HomeStack = createStackNavigator({
home: {
screen: HomeScreen,
navigationOptions: {
...headerNavigationOptions,
headerTitle: '',
headerBackTitle: 'Home'
}
},
detail: {
screen: DetailScreen,
navigationOptions: {
...headerNavigationOptions,
headerTitle: 'Detail'
}
}
});
HomeStack.navigationOptions = ({ navigation }) => {
return {
tabBarVisible: (navigation.state.index === 0)
};
};
const AddStack = createStackNavigator({
add: {
screen: AddScreen,
navigationOptions: {
header: null
}
}
});
AddStack.navigationOptions = ({ navigation }) => {
return {
tabBarVisible: (navigation.state.index === -1)
};
};
const ProfileStack = createStackNavigator({
profile: {
screen: ProfileScreen,
navigationOptions: {
...headerNavigationOptions,
headerTitle: '',
}
},
setting1: {
screen: Setting1Screen,
navigationOptions: {
...headerNavigationOptions,
headerTitle: 'Setting1'
} },
setting2: {
screen: Setting2Screen,
navigationOptions: {
...headerNavigationOptions,
headerTitle: 'Setting2'
}
}
});
ProfileStack.navigationOptions = ({ navigation }) => {
return {
tabBarVisible: (navigation.state.index === 0)
};
};