Reduxを利用することの利点は、Fluxアーキテクチャを組み込むことだけではありません。Reduxはかなり熱いフレームワークであり、Reduxのエコシステムができています。
awesome-refuxにはExampleだけじゃなくライブラリも列挙されてます。必ずしもReact Nativeで利用できるかは保証できませんが、ライブラリのgithub issueやコードを覗くとReactNativeがサポートされているような記述を見つけることができます。storageやi18nのライブラリもあるので、Nativeでそれらのエコシステムを利用し、開発スピードを上げることができます。
今回は、ecosystemライブラリの一つであるRedux-formのReact Nativeにどうやって組み込むかを説明します。
redux-form
HTMLでいうとinputなどのフォームを作るライブラリです。Nativeでもログイン画面などText入力を受けつけるので、これを使うことでFormのvalidation等を実装できます。
Install redux-form
Redux本体と同じくReactNativeのReact0.14互換対応待ちなので少し古いバージョンで動かします。package.json
に下記の行を追加し、npm install
してインストールします。
"dependencies": {
"redux-form": "^3.0.11",
コード
Formを組み込みたいでredux-formを呼び出します。これもredux本体と同じようにredux-form/native
でimportする形になります。
import {reduxForm} from 'redux-form/native';
storeとreuxForm()
でコンポーネント(下記の例ではLogin)との関連付けを行います。form名、フィールドを使うかを記述します。
export default reduxForm({
form: 'login',
fields: ['email', 'password']
})(Login);
そして、いつものようにpropsからStoreのstateを取得します。
const {dispatch, fields: { email, password }, handleSubmit } = this.props;
{...email}
を入力部に入れれば完成です。
<TextInput
style={Styles.inputText}
{...email}
placeholderTextColor="#ccc"
keyboardType='email-address'
/>
ここにemail validationを追加したい場合は、validationを作り、
const validate = values => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
return errors
}
reduxForm()
に読み込ませます。
//export default Login;
export default reduxForm({
form: 'login',
validate, //追加
fields: ['email', 'password']
})(Login);
すると、下記のようにInvalidというメッセージが表示されます。
全体のコードは下記のようになります。
import React, { Text, View, TextInput } from 'react-native';
import {reduxForm} from 'redux-form/native';
import { login } from '../actions';
import Button from 'react-native-button';
import Styles from '../components/Styles';
const validate = values => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
return errors
}
let Login = React.createClass({
getInitialState(){
return {
email: "",
password: "",
}
},
render(){
const {dispatch, fields: { email, password }, handleSubmit } = this.props;
return (
<View>
<Text style={Styles.label}>Email</Text>
<View style={Styles.separator} />
<TextInput
style={Styles.inputText}
{...email}
placeholderTextColor="#ccc"
keyboardType='email-address'
/>
{email.touched && email.error && <Text>{email.error}</Text>}
<View style={Styles.separator} />
<Text style={Styles.label}>Password</Text>
<View style={Styles.separator} />
<TextInput
style={Styles.inputText}
{...password}
secureTextEntry={true}
placeholderTextColor="#ccc"
/>
<View style={Styles.separator} />
<Button onPress={handleSubmit(data => dispatch( login(data.email, data.password) ))} style={{marginTop: 20, color: '#F0614F'}}>Login</Button>
</View>
)
}
});
//export default Login;
export default reduxForm({
form: 'login',
validate,
fields: ['email', 'password']
})(Login);
Summary
今日はReduxのecosystemを利用して、React Nativeのアプリを書いてみました。まさにLearn once, write anywhere"ですね。Web技術がそのままNativeで生きてきます。まだ沢山Reduxのecosystemライブラリがあるので是非試してみてください。