#react-native+redux+react-navigationサンプル
##changeTextサンプル
###作るもの
・TextInputに入力された文字をボタンを押したらTextに表示
###注意点
・TextInputの値を直接 $('TextInput').val() みたいに取得できないので、リアルタイムでその値をstateに保存する必要がある。
今回は前回記事で書いたテンプレートをベースに差分だけUPしていきますね。
##ページ遷移なし
全部のソースはここ:changeTextSample
まずはStateとReducerの設計。
今回Stateは、
・TextInputの値保存用(in_txt)
・Textに表示する用(out_txt)
の2つ。
Reducerの値変更パターンは、
・TextInputの値が変わったらin_txtを変更
・ボタンが押されたらout_txtにin_txtを代入
・それ以外
の3つ。
それではソース
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に追加してください。
import { combineReducers } from 'redux';
import navReducer from './navReducer';
import changeTextReducer from './changeTextReducer';//ここ
const allReducers = combineReducers({
nav:navReducer,
ct:changeTextReducer, //ここ
});
export default allReducers;
次にActionファイルの作成。 今回使うActionは ・TextInputが編集された時 ・ボタンが押された時 の2個
export const editText = text => {
return {
type: 'EDIT',
in_text: text,
}
}
export const pressBtn = () => {
return {
type: 'PRESS_BTN',
}
}
そしたら画面を作っていきます。 詳しい説明は割愛。 Button使うと見た目があれなのでTouchableOpacity使ってます。
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);
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に追加してください。
import { StackNavigator } from 'react-navigation';
import Input from './Input';//ここ
export const rootCom = 'Input';//1ページだけなのでルート要素としてここにも書く
const pageNation = StackNavigator({
Input: { //ここから
screen:Input,
}, //ここまで
});
export default pageNation;
以上で画面遷移なしは完成。
##画面遷移あり
全部のソースはここ:changeTextSample2
画面遷移なしverをつくって、そこの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'); で画面遷移してます。
次に、遷移後の画面を作成
onPressのところのgoBack();で元の画面(入力画面)に戻ります。
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);
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に追加
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;
以上で終わりです。
なんとなくでもreact-nativeでのアプリケーション開発の感覚がつかめてれば幸いです。