Help us understand the problem. What is going on with this article?

ReactNativeでサクッとReactjs記事リーダーを作ってみる

More than 5 years have passed since last update.

ReactNativeとは

ReactNative http://facebook.github.io/react-native/

ReactNativeとはReactjsベースでネイティブアプリを構築できるSDKで、Facebookが先日リリースしました。ちなみにFacebook GroupのアプリがReactNative製なんだそうな。
現在はiOSのみの対応となっていますが、将来的にはその他プラットフォームにも対応していくものと思われます。
内部ではReactjsの描画結果をUIKitの各要素に変換して描画しているようです。
触ってみたいという方は、3分くらいで準備できますのでやってみましょう。
http://facebook.github.io/react-native/docs/getting-started.html#content

作ったもの

とりあえずどういった作法で書いていくものなのか気になったので、QiitaのAPIを利用して、Reactjsの記事を表示するアプリを書いてみました。
デザイン部分のコードを除けばおおよそ100行くらいでかける模様です。
UINavigationControllerの扱いやタッチイベントの扱いが元のUIKitと比較すると独特ですが、それ以外は割と実用的にReactiveなiOS開発が可能なツールのようです。

ReactQiita.png

ソースコード

index.js
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  Image,
  NavigatorIOS,
  TouchableWithoutFeedback,
  WebView
} = React;

var QIITA_URL = "https://qiita.com/api/v2/tags/reactjs/items";

// ベースのUINavigationControllerに該当するもの
var ReactQiitaNavigator = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
        style={styles.navigator}
        initialRoute={{
          component: ReactQiitaList,
          title: 'ReactQiita',
      }}/>
    );
  }
})

// 記事一覧リスト
var ReactQiitaList = React.createClass({
  getInitialState: function() {
    return {
      items: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
      loaded: false,
    };
  },

  componentDidMount: function() {
    this.fetchData();
  },

  render: function() {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <ListView
        dataSource={this.state.items}
        renderRow={this.renderItem}
        style={styles.listView}/>
    );
  },

  renderLoadingView: function() {
    return (
      <View style={styles.container}>
        <Text>
          Loading movies...
        </Text>
      </View>
    );
  },

  renderItem: function(item, sectionID, rowID) {
    return (
      <TouchableWithoutFeedback  onPress={() => this.onPressed(item)}>
      <View style={styles.container}>
        <Image
          source={{uri: item.user.profile_image_url}}
          style={styles.thumbnail}/>
        <View style={styles.rightContainer}>
          <Text style={styles.title}>{item.title}</Text>
          <Text style={styles.name}>{item.user.id}</Text>
        </View>
      </View>
      </TouchableWithoutFeedback>
    );
  },

  // API呼び出し
  fetchData: function() {
    fetch(QIITA_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          items: this.state.items.cloneWithRows(responseData),
          loaded: true,
        });
      })
      .done();
  },

  //セルのタッチイベント
  onPressed: function(item) {
    this.props.navigator.push({
      title: item.title,
      component: ReactQiitaItemView,
      passProps: { url: item.url }
    })
  },
});

// 記事閲覧用のWebView
var ReactQiitaItemView = React.createClass({
  render: function() {
    return (
      <WebView
        url={this.props.url}/>
    )
  }
});

// 各種デザイン要素
var styles = StyleSheet.create({
  navigator: {
    flex: 1
  },
  container: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  rightContainer: {
    flex: 1,
  },
  title: {
    fontSize: 15,
    margin: 8,
    textAlign: 'left',
  },
  name: {
    fontSize: 12,
    margin: 8,
    textAlign: 'left',
  },
  thumbnail: {
    width: 80,
    height: 80,
    margin: 2,
  },
  listView: {
    backgroundColor: '#FFFFFF',
  },
});

AppRegistry.registerComponent('ReactQiita', () => ReactQiitaNavigator);

作ってみての感想

これを一通り作るのに30分も掛からないくらいには使いやすいのと、その他クロスプラットフォームなツールと比べてもパフォーマンス問題はあまり気にならなそうに感じました。
あと、個人的には以前ReactiveCocoaの作法にあまり馴染めなかったのですが、ReactNativeはJavascriptとReactiveな部分の相性が良く、ネイティブアプリにReactiveな設計を持ち込むのには非常に実用的なSDKではないかと思いました。
Objective-Cで記述したものを組み合わせることも可能なようなので、これまでの資産がどれだけ活かせるか調べてみたい次第。もう少し触ってみます。

y_matsuwitter
DMM.com CTO。正座してる人。
http://medium.com/@y_matsuwitter/
dmmcom
総合エンタテイメントサイト「DMM.com」を運営。会員数は2,900万人を突破。動画配信、FX、英会話、ゲーム、太陽光発電、3Dプリンタなど40以上のサービスを展開。沖縄での水族館事業参入、ベルギーでのサッカークラブ経営など、様々な事業を手掛ける。また2018年より若手起業家の支援を強化、「DMM VENTURES」による出資や、M&Aなどを積極的に展開している。
https://dmm-corp.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした