react-native+redux+react-navigationサンプル

#react-native+redux+react-navigationサンプル
<br />
##changeTextサンプル
###作るもの
　・TextInputに入力された文字をボタンを押したらTextに表示
<br />
###注意点
　・TextInputの値を直接　$('TextInput').val()　みたいに取得できないので、リアルタイムでその値をstateに保存する必要がある。
<br />
　今回は[前回記事](https://qiita.com/shoichi1023/items/3aac40920d3348937d2b)で書いたテンプレートをベースに差分だけUPしていきますね。
##ページ遷移なし
全部のソースはここ：[changeTextSample](https://github.com/shoichi1023/changeText)
<br/>
まずはStateとReducerの設計。

今回Stateは、
　・TextInputの値保存用(in_txt)
　・Textに表示する用(out_txt)
の2つ。

Reducerの値変更パターンは、
　・TextInputの値が変わったらin_txtを変更
　・ボタンが押されたらout_txtにin_txtを代入
　・それ以外
の3つ。

それではソース

```changeTextReducer.js

const state = {
	out_text:'',
	in_text:'',
}

const changeTextReducer = (state=state, action) => {
	switch(action.type){
		
		case 'EDIT':
			return{
				...state,
				in_text: action.in_text,
			};

		case 'PRESS_BTN':
			return{
				...state,
				out_text: state.in_text,
			};

		default:
			return { ...state };
	}
}

export default changeTextReducer

```
Reducerを作ったらallReducer.jsに追加してください。

```allReducer.js
import { combineReducers } from 'redux';
import navReducer from './navReducer';
import changeTextReducer from './changeTextReducer';//ここ

const allReducers = combineReducers({
	nav:navReducer,
	ct:changeTextReducer, //ここ
});

export default allReducers;
```

<br />
次にActionファイルの作成。
今回使うActionは
　・TextInputが編集された時
　・ボタンが押された時
の２個

```changeTextActions.js

export const editText = text => {
	return {
		type: 'EDIT',
		in_text: text,
	}
}

export const pressBtn = () => {
	return {
		type: 'PRESS_BTN',
	}
}
```
<br />
そしたら画面を作っていきます。
詳しい説明は割愛。
Button使うと見た目があれなのでTouchableOpacity使ってます。

```jsx:Input.js
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Text, View, TextInput, TouchableOpacity } from 'react-native';
import styles from './Input_style';
import * as actions from './changeTextActions';

class Input extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.txt}>『 {this.props.out_text} 』</Text>
        <TextInput style={ styles.txtIn } onChangeText={ (text) => { this.props.editText(text) } } />
        <TouchableOpacity style={styles.tOpa} onPress={ () => { this.props.pressBtn(); } }>
          <Text style={styles.btnTxt}>変更</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const mapStateToProps = state => state.ct;
const mapDispatchToProps = dispatch => ({
  ...bindActionCreators(actions, dispatch)
});

export default connect(mapStateToProps,mapDispatchToProps)(Input);
```

```Input_style.js
import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  txt: {
    fontSize: 25,
  },
  txtIn: {
    height: 40,
    width: 300,
    marginTop: 20,
    fontSize: 25,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 5,
    textAlign: 'center',
  },
  tOpa: {
    width: 100,
    height: 50,
    padding: 10,
    borderRadius: 10,
    backgroundColor: 'lightgray',
    alignItems: 'center',
    justifyContent: 'center',
    margin: 20,
  },
  btnTxt: {
    fontSize: 18,
  },
});

export default styles;
```

画面を作成したらpageNationに追加してください。

```pageNation.js
import { StackNavigator } from 'react-navigation';
import Input from './Input';//ここ

export const rootCom = 'Input';//1ページだけなのでルート要素としてここにも書く

const pageNation = StackNavigator({
  Input: {              //ここから
    screen:Input, 
  },                    //ここまで
});

export default pageNation;
```

以上で画面遷移なしは完成。
<br />
##画面遷移あり
全部のソースはここ：[changeTextSample2](https://github.com/shoichi1023/changeText2)
画面遷移なしverをつくって、そこのInput.jsを下記のように修正

```jsx:Input.js
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Text, View, TextInput, TouchableOpacity } from 'react-native';
import styles from './Input_styles';
import * as actions from './changeTextActions';

class Input extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <TextInput style={ styles.txtIn } onChangeText={ (text) => { this.props.editText(text); } } />
        <TouchableOpacity style={styles.tOpa} onPress={ () => { this.props.pressBtn(); this.props.navigation.navigate('Result'); } }>
          <Text style={styles.btnTxt}>変更</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const mapStateToProps = state => state.ct;
const mapDispatchToProps = dispatch => ({
  ...bindActionCreators(actions, dispatch)
});

export default connect(mapStateToProps,mapDispatchToProps)(Input);
```
表示用のTextがなくなっただけです。
onPressのところの　this.props.navigation.navigate('Result');　で画面遷移してます。
<br/>
次に、遷移後の画面を作成
onPressのところのgoBack();で元の画面(入力画面)に戻ります。

```jsx:Result.js
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Text, View, TextInput, TouchableOpacity } from 'react-native';
import styles from './Result_styles';

class Result extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.txt}>『 {this.props.out_text} 』</Text>
        <TouchableOpacity style={styles.tOpa} onPress={ () => { this.props.navigation.goBack(); } }>
          <Text style={styles.btnTxt}>戻る</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const mapStateToProps = state => state.ct;


export default connect(mapStateToProps)(Result);
```

```Result_style.js
import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  txt: {
    fontSize: 25,
  },
  tOpa: {
    width: 100,
    height: 50,
    padding: 10,
    borderRadius: 10,
    backgroundColor: 'lightgray',
    alignItems: 'center',
    justifyContent: 'center',
    margin: 20,
  },
  btnTxt: {
    fontSize: 18,
  },
});

export default styles;
```

例のごとくpageNationに追加

```pageNation.js
import { StackNavigator } from 'react-navigation';
import Input from './Input';
import Result from './Result';  //ここ

export const rootCom = 'Input';

const pageNation = StackNavigator({
  Input: {
    screen:Input,
  },
  Result: {             //ここ
    screen:Result,
  },
});

export default pageNation;
```
以上で終わりです。
<br />
なんとなくでもreact-nativeでのアプリケーション開発の感覚がつかめてれば幸いです。
<br />