Open18

React Native

tatatsurutatatsuru

基本構造

import {
  StyleSheet,
  Text,
  View,
  ...
} from "react-native";

export default function App() {
  <View style={styles.container}>
    <Text>Hello World!!!</Text>
  </View>
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexGrow: 1,
    backgroundColor: "#fff",
  },
});
tatatsurutatatsuru

おかしくなったらどーしよ

pnpm installでいろんなものを入れてたらおかしくなった。
例えば、react-nativeをinstallしてもTSの方でエラーが出てしまう。。。

そんな時は下記コマンドを実行する。

expo r -c

そうすると、
**足りてないmoduleをinstallしますか?**と聞いてくれる(という経験をした。)

tatatsurutatatsuru

カードなどをループするとき

const gap = 10;
export default function App() {
  return (
    <FlatList
      contentContainerStyle={{ gap, alignItems: "center" }}
      columnWrapperStyle={{ gap }}
      data={cardData}
      numColumns={2}
      keyExtractor={(item, index) => `${item}${index}`}
      renderItem={(itemData) => (
         <Card
           key={itemData.index}
           cardTitle={itemData.item.cardTitle}
           cardText={itemData.item.cardText}
            image={itemData.item.image}
         />
      )}
     />
  );
}

これで2カラムのレイアウトができる。

tatatsurutatatsuru

widthの小技

const screenWidth = Dimensions.get("window").width;
const cardWidth = (screenWidth * number) / 100;

windowの横幅に対して〜%という感じで設定できる

tatatsurutatatsuru

expo router

https://expo.github.io/router/docs/

順番通りにやると、勝手にディレクトリを作ってくれる。
Stackという固定ヘッダーみたいなのがあって、optionで色々いじれる。
iOSだと、headerTitleがcenterにしか配置できないのが難点。

自前のheaderをStack扱いにできない?

tatatsurutatatsuru

ボタンカード

import { StatusBar } from "expo-status-bar";
import { Link, Tabs } from "expo-router";
import {
  StyleSheet,
  Text,
  View,
  Image,
  Pressable,
  ImageSourcePropType,
  Dimensions,
  TouchableOpacity,
} from "react-native";

import { useNavigation, NavigationProp } from "@react-navigation/native";

interface pageNameProps {
  menu: undefined;
}

export default function Card({
  cardTitle,
  cardText,
  image,
}: {
  cardTitle: string;
  cardText: string;
  image: ImageSourcePropType;
}) {
  const navigation = useNavigation<NavigationProp<pageNameProps>>();

  const handleCardPress = () => {
    navigation.navigate("menu");
  };

  return (
    <View>
      <TouchableOpacity style={styles.card} onPress={handleCardPress}>
        <Text style={styles.cardTitle}>{cardTitle}</Text>
        <Text style={styles.cardText}>{cardText}</Text>
        <Image source={image} style={styles.image} />
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    position: "relative",
    overflow: "hidden",
    backgroundColor: "#fff",
    paddingTop: 20,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 0,
    height: 180,
    width: Dimensions.get("window").width / 2 - 20,
    borderWidth: 1,
    borderColor: "#ddd",
    borderRadius: 15,
  },

  cardTitle: {
    fontSize: 14,
    fontWeight: "bold",
    color: "#000",
    marginBottom: 5,
  },

  cardText: {
    fontSize: 10,
    fontWeight: "bold",
    color: "#9B9BAB",
  },

  image: {
    position: "absolute",
    bottom: 0,
    right: 0,
    width: 130,
    height: 100,
  },
});