LoginSignup
8
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-05-31

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つ。

それではソース

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;



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

changeTextActions.js

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

export const pressBtn = () => {
    return {
        type: 'PRESS_BTN',
    }
}



そしたら画面を作っていきます。
詳しい説明は割愛。
Button使うと見た目があれなのでTouchableOpacity使ってます。

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;

以上で画面遷移なしは完成。

画面遷移あり

全部のソースはここ:changeTextSample2
画面遷移なしverをつくって、そこのInput.jsを下記のように修正

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();で元の画面(入力画面)に戻ります。

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;

以上で終わりです。


なんとなくでもreact-nativeでのアプリケーション開発の感覚がつかめてれば幸いです。

8
3
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
8
3