ReactNativeのDimensionsで取れる高さはReactNavigationのフッターとかあると変わるのか

ReactNavigationを使うと上下にタブを作ってくれるが、これがあるとDimensionsで取れる高さは変わるのか気になったのでメモ。

使用機種はIPhone11

import {Dimensions} from 'react-native';

const {height} = Dimensions.get('screen');
console.log(height);

結果どちらも896

変化はなかった。

TypeScriptでコンポーネントがpropsとして受け取る型を再現する

TSとRNでコンポーネントAを作っているとき、そのコンポーネントAに「FlatListに渡せるProps」をPropsとして渡せるように型を作りたかった。

ComponentPropsを使えば作りやすい。

import React, { ComponentProps } from "react";

type Props = {
  foo: string
  bar: number
  flatListProps: ComponentProps<typeof FlatList>
}

const A = ({
  foo,
  bar,
  flatListProps
}: Props) => {
  return <FlatList {...flatListProps} />
}

FlatListの中でも data, renderItem, getItemを除外した型を作りたい場合は

Omit<ComponentProps<typeof FlatList>, "data" | "renderItem" | "getItem">

でいけた

prismaのクエリで1対多の「多に存在しないデータ」という条件で1を取り出す

ユーザー、お知らせ、ユーザーが既読したお知らせ、というデータ(テーブル)があり「ユーザーが既読していない全てのお知らせ」をprismaのクエリのみだけで取り出したい。

schema.prismaは以下

model User {
  id Int @id @default(autoincrement())
  name String
  readNotifications UserReadNotification[]
}

model Notification {
  id Int @id @default(autoincrement())
  title String
  text String
  alreadyRead UserReadNotification[]
}

model UserReadNotification {
  id Int @id @default(autoincrement())
  userId Int
  notificationId Int
  user User @relation(fields: [userId], references: [id])
  notification UserNotification @relation(fields: [notificationId], references: [id])
}

ソースコード

const prisma = new PrismaClient();
const userId = 1

const unreadData = await prisma.Notification.findMany({
    where: {
      alreadyRead: {
        none: { // noneを指定
          userId
        },
      },
    },
  });

noneはprismaの1:多の「多」からデータをフィルタリングするためのクエリ。 これをつけることで、指定したリレーション(ここではalreadyRead)の全てのデータの指定したカラム(ここではuserId)に指定したデータ(ここではuserId)が存在しなければそのデータを返す。ここではfindManyを使っているので条件を満たすデータを全て返す。 これで、「既読していない全てのお知らせ」言い換えると「UserReadNotificationのuserIdに指定したuserIdが存在しない全てのNotification」を取り出すことができる。

prismaのクエリ便利だな〜と思う。他にも「多」からデータをフィルタリングするためのクエリはある。

www.prisma.io

シンプルにするために実際に作ったコードを変更しているので、間違ったとこあったらごめんなさい。

Reactで異なるオリジンのAPI叩いたら404が返ってきた時の対処法

フロントはTypeScriptとReact、バックエンドはNodeで書いていて、このサーバーはAPI用のものとしてフロントを返すサーバーとは別のもの、という構成で作っていた。

具体的には

フロントのページ返すサーバーが localhost:3000

APIサーバーが localhost:4000

といった感じ。

 

この状況でReactからaxiosを使いAPIサーバーを叩いた。

const origin = "http:/localhost:4000";
const baseUrl = `${origin}/api/v1`;

// 404エラー
await axios.post(
          `${baseUrl}/users`,
          { name },
        );

これだと "http:/localhost:3000/localhost:4000" にリクエストが送られてしまってエラーになっていた。


対処法
package.jsonに proxy を設定する

create-react-app.dev

To tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json

{
...
"proxy": "http://localhost:4000"
}

こうした後にソースコードも変更

const baseUrl = `/api/v1`;

await axios.post(
          `${baseUrl}/users`,
          { name },
        );

いったんフロント返す側のサーバダウンさせてタブも消す。その後再び yarn start で立ち上げたら無事叩けるようになった。

なぜaixosでURLを指定しても "http:/localhost:3000/localhost:4000/~" にリクエストされてしまったのか具体的な部分は不明。
ReactNativeではエラー出なかったのでReactの設定だとは思う。