LoginSignup
10
10

More than 3 years have passed since last update.

React Navigationの画面遷移時に再レンダリングを行う

Posted at

やったこと

  • 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種類

  1. 高階コンポーネントwithNavigationFocusを使用する
  2. 今回の、EventListerを使用して'didMount'をListenする

高階コンポーネントとは

あるコンポーネントを受け取って新規のコンポーネントを返すような関数です
https://ja.reactjs.org/docs/higher-order-components.html

詳しくは調べていないのですが、概要は以下です。

  • react-navigationが持つisFocusedというpropsは、対象画面がfocusされているかによって、truefalseとなる。
  • この場合、毎回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)
      };
    };
10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10