LoginSignup
31
18

More than 5 years have passed since last update.

redux + react-navigation

Posted at

react-native+reduxを触り始めてそんなに経ってませんので備忘録

react-navigationのStateをreduxで管理しようという試みです。

公式リファレンスだとコードが一箇所にまとめられてて
パッと見わかりづらかったのでメモ(自分だけ?)

1. Navigationのコンポーネントを作成

今回の例だとこんな感じ

Navigation.js
import {
    StackNavigator
} from 'react-navigation';

import screens from './screens';

export default StackNavigator({
    Splash: {
        screen: screens.Splash,
        navigationOptions: {
            header: null,
        }
    },
    MainScreen: {
        screen: screens.MainScreen,
        navigationOptions: {
            title: 'メイン画面',
            headerBackTitle: null,
        }
    },
    DetailScreen: {
        screen: screens.EventScreen,
        navigationOptions: {
            title: '詳細画面',
        }
    }
})

スプラッシュ画面→メイン画面←→詳細画面
みたいな構成だと仮定。

2. NavigationのStateを加工するReducerを作成

これはほぼ公式通りに作れば良さそう。
getStateForActionがよしなにNavigationのStateを作ってくれる。

navReducer.js
import nav from './Navigation'; //(1)で作ったやつ

// 初期画面名を指定して初期ステートを作成
const initialState = nav.router.getStateForAction(nav.router.getActionForPathAndParams('Splash'));

export default (state = initialState, action) => {
  const nextState = nav.router.getStateForAction(action, state);

  return nextState || state;
};

3. StoreにReducerを渡す

Store.js
import navReducer from './reducers/navReducer';

const appReducer = combineReducers({
  nav: navReducer,
  ...
});

4. ReduxとのConnect(コンテナ作成)

実際は、いちいちContainerとComponentを分けなくてもよさげです。
コメントのところはフワッとした理解なので、コードを見てみようかと思います。

NavigationContainer.js
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { addNavigationHelpers } from 'react-navigation';

import Navigation from '../routes/Navigation';

class Nav extends Component {
  render() {
    // addNavigationHelpersが生成したnavigationが、
    // actionをdispatchしてくれて
    // reducerが新しいNavigationのStateを作って
    // 新しいStateでNavigationが更新されるという仕組み(多分)
    return (
      <Navigation
        navigation={addNavigationHelpers({
          dispatch: this.props.dispatch,
          state: this.props.nav,
        })}
      />
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
  nav: state.nav
});

export default connect(mapStateToProps)(Nav);

5. Providerの中でコンテナを使う

普通のreduxのように使えばOK

App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Navigation from './containers/NavigationContainer';

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Navigation />
      </Provider>
    );
  }
}

もうちょっと掘り下げて色々やってみようかと思います。
react-native-router-fluxからもうまく移行できるようなやり方を模索中です。

参考

公式リファレンス
https://reactnavigation.org/docs/guides/redux

31
18
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
31
18