0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react native でとりあえず機能を試す用の下地アプリ

Last updated at Posted at 2018-06-22

既存のプロジェクトであれこれ試す時は、シンプルなプロジェクトで試したい
それに、アプリをつくっていると、だんだん適当になるので、、適度に挙動を確認

3つの画面を react-native-router-flux で遷移しつつ、ライフサイクルがどのような動いてるかを確認するようのテンプレート

1つのStoreを持っていて、

  • A (storeの表示)
  • B (storeの更新1)
  • C (storeの更新2)

となるように動く。イメージとしてはプロフィールの表示、編集、編集完了という感じ。
storeの更新、ページの遷移時の引数、などなどで混乱ないように

reduxは、redux-aggregateを使うのが最近のお気に入り。

###とりあえずアプリ作成###

react-native init sampleApp

###環境###
生成された package.json

package.json
{
  "name": "sampleApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.3.1",
    "react-native": "0.55.4"
  },
  "devDependencies": {
    "babel-jest": "23.0.1",
    "babel-preset-react-native": "4.0.0",
    "jest": "23.1.0",
    "react-test-renderer": "16.3.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

###必要なパッケージを足す###

yarn add react-native-router-flux react-redux redux redux-aggregate redux-devtools-extension

##ベースとなるアプリ##
Qiitaの仕様で.jsxにしてるけど、ほんとは.js

app/index.jsx
import React, { Component } from 'react';
import { Router, Scene } from 'react-native-router-flux';
import Ascreen from './containers/Ascreen';
import Bscreen from './containers/Bscreen';
import Cscreen from './containers/Cscreen';

class App extends Component {
  render() {
    return (
      <Router>
        <Scene key="navigation" hideNavBar={false}>
          <Scene key="ascreen" component={Ascreen} />
          <Scene key="bscreen" component={Bscreen} />
          <Scene key="cscreen" component={Cscreen} />
        </Scene>
      </Router>
    );
  }
}

export default App;
app/countainers/Ascreen.jsx
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { Actions } from 'react-native-router-flux';

class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Screen A</Text>
        <Button
          onPress={() => {
            Actions.bscreen();
          }}
          title="NEXT"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

export default App;
app/countainers/Bscreen.jsx
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { Actions } from 'react-native-router-flux';

class BScreen extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Screen B</Text>
        <Button
          onPress={() => {
            Actions.cscreen();
          }}
          title="NEXT C"
        />
        <Button
          onPress={() => {
            Actions.pop();
          }}
          title="BACK A"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default BScreen;
app/countainers/Cscreen.jsx
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { Actions } from 'react-native-router-flux';

class CScreen extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Screen C</Text>
        <Button
          onPress={() => {
            Actions.pop();
          }}
          title="BACK B"
        />
        <Button
          onPress={() => {
            Actions.popTo('ascreen');
          }}
          title="BACK A"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default CScreen;

##store追加##
追加するとこんな感じ

app/index.jsx
import React, { Component } from 'react';
import { Router, Scene } from 'react-native-router-flux';
import { Provider } from 'react-redux';
import { store } from './store';
import Ascreen from './containers/Ascreen';
import Bscreen from './containers/Bscreen';
import Cscreen from './containers/Cscreen';

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router>
          <Scene key="navigation" hideNavBar={false}>
            <Scene key="ascreen" component={Ascreen} />
            <Scene key="bscreen" component={Bscreen} />
            <Scene key="cscreen" component={Cscreen} />
          </Scene>
        </Router>
      </Provider>
    );
  }
}

export default App;
app/store.js
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { createAggregate } from 'redux-aggregate';
import { composeWithDevTools } from 'redux-devtools-extension';

import { ProfileST, ProfileMT } from './models/profile';

const middleware = [];

export function defineStore(reducer) {
  return createStore(
    combineReducers(reducer),
    composeWithDevTools(applyMiddleware(...middleware))
  );
}

export const Profile = createAggregate(ProfileMT, 'profile/');

export const store = defineStore({
  profile: Profile.reducerFactory({ ...ProfileST, name: 'PROFILE' }),
});
app/models/profile.js
export const ProfileST = {
  uid: '',
};
// @ Queries
function getUid(state) {
  return `uid:${state.uid}`;
}
export const ProfileQR = {
  getUid,
};
// @ Mutations
function updateUid(state, payload) {
  return { ...state, uid: payload };
}
function resetUid(state) {
  return { ...state, uid: '' };
}
export const ProfileMT = {
  updateUid,
  resetUid,
};
app/countainers/Ascreen.jsx
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { Actions } from 'react-native-router-flux';
import { connect } from 'react-redux';
import { Profile } from '../store';
import { ProfileQR } from '../models/profile';

class AScreen extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Screen A</Text>
        <Text>{this.props.userId}</Text>
        <Button
          onPress={() => {
            this.props.updateUid('Taro');
            Actions.bscreen();
          }}
          title="NEXT"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

export default connect(
  ({ profile }) => ({ profile, userId: ProfileQR.getUid(profile) }),
  {
    ...Profile.creators,
  }
)(AScreen);

ソースコード

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?