何かやってみるブログ

興味をもったことに関して書いています。技術系の記事が多いです。

React Native ✕ Expoでとりあえずto doリストを作成してみる (作成と一覧表示)

React Nativeに最近ハマっているので、整理する意味でtodoリストを作成してみました。 せっかくなのでチュートリアルにまとめてみました。Macで開発するので、iPhoneのシュミレーターで確認していきます。

環境構築

  • nodeをインストール nodeのバージョンが確認できればOKです。
$ node --version
v12.14.0
  • expo cliをインストール
$ npm install expo-cli --global
  • 今回作成するプロジェクトを作成 いろいろありますが、今回はManaged workflowのblankテンプレートで作成していきます。
$ expo init  todo
? Choose a template: (Use arrow keys)
  ----- Managed workflow -----
❯ blank                 a minimal app as clean as an empty canvas
  blank (TypeScript)    same as blank but with TypeScript configuration
  tabs                  several example screens and tabs using react-navigation
  ----- Bare workflow -----
  minimal               bare and minimal, just the essentials to get you started
  minimal (TypeScript)  same as minimal but with TypeScript configuration
$ cd todo 
  • expo startとコマンドをうって、サーバーが立ち上がればOKです。

f:id:s-takaya1027:20200313223618p:plain

  • ブラウザからRun on iOS simulatorをクリックして以下のようにiOSシュミレーターを起動することを確認します。 f:id:s-takaya1027:20200313225158p:plain

UIを構築する。

import React from "react";
import {
  StyleSheet,
  Text,
  SafeAreaView,
  TextInput,
  TouchableOpacity,
  View
} from "react-native";

const Todo = () => {
  return (
    <View>
      <Text>やること</Text>
    </View>
  );
};

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.headerTitle}>Todoリスト</Text>
      <TextInput style={styles.todoInput} />
      <TouchableOpacity style={styles.button}>
        <Text style={styles.buttonText}>追加する</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  headerTitle: {
    textAlign: "center",
    fontSize: 30
  },
  todoInput: {
    backgroundColor: "#fff",
    width: "70%",
    alignSelf: "center",
    marginTop: 20,
    padding: 10,
    fontSize: 20
  },
  container: {
    backgroundColor: "#ddd",
    flex: 1
  },
  button: {
    backgroundColor: "blue",
    width: "60%",
    alignSelf: "center",
    marginTop: 10
  },
  buttonText: {
    color: "#fff",
    fontSize: 20,
    textAlign: "center",
    fontWeight: "bold",
    padding: 10
  }
});

export default App;

シュミレーターで確認するといかのようになります。 f:id:s-takaya1027:20200314002946p:plain

機能を追加する

import React, { useState, useEffect } from "react";
import {
  StyleSheet,
  Text,
  SafeAreaView,
  TextInput,
  TouchableOpacity,
  View,
  FlatList
} from "react-native";

const Todo = props => {
  useEffect(() => {
    console.log(props.content);
  }, []);
  return (
    <View style={styles.todo}>
      <Text style={styles.todoText}>{props.content}</Text>
    </View>
  );
};

const App = () => {
  const [content, setContent] = useState("");
  const [todos, setTodos] = useState([]);
  const [id, setId] = useState(0);

  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.headerTitle}>Todoリスト</Text>
      <TextInput
        style={styles.todoInput}
        onChangeText={text => setContent(text)}
        value={content}
      />
      <TouchableOpacity
        style={styles.button}
        onPress={() => {
          //空文字はNG
          if (content == "") {
            return false;
          }
          setId(id + 1);
          setTodos(todos.concat([{ id: id, content: content }]));
          console.log(todos);
          setContent("");
        }}
      >
        <Text style={styles.buttonText}>追加する</Text>
      </TouchableOpacity>
      <FlatList
        data={todos}
        renderItem={({ item }) => {
          return <Todo content={item.content} />;
        }}
        keyExtractor={item => item.id.toString()}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  headerTitle: {
    textAlign: "center",
    fontSize: 30
  },
  todoInput: {
    backgroundColor: "#fff",
    width: "70%",
    alignSelf: "center",
    marginTop: 20,
    padding: 10,
    fontSize: 20
  },
  container: {
    backgroundColor: "#ddd",
    flex: 1
  },
  button: {
    backgroundColor: "blue",
    width: "60%",
    alignSelf: "center",
    marginTop: 10,
    marginBottom: 20
  },
  buttonText: {
    color: "#fff",
    fontSize: 20,
    textAlign: "center",
    fontWeight: "bold",
    padding: 10
  },
  todo: {
    height: 50,
    backgroundColor: "#fff",
    borderRadius: 4,
    borderWidth: 0.5,
    borderColor: "#d6d7da",
    padding: 10
  },
  todoText: {
    textAlign: "center",
    fontSize: 20
  }
});

export default App;

以上のように実装するとこんな感じで動きます。

youtu.be