LoginSignup
2

More than 3 years have passed since last update.

React-nativeで環境だけ整えて満足した記事(react-native + expo + typescript + NativeBase + why-did-you-render-eslint)

Posted at

overview

以下の導入方法を示す。
この記事は結構丁寧なメモです。

  • react-native
  • expo
  • typescript
  • NativeBase
  • why-did-you-render
  • eslint

expo install

$ npm install -g expo-cli

プロジェクト用意

$ expo init react-native-sample
✔ Choose a template: › tabs (TypeScript)     several example screens and tabs using react-navigation and TypeScript
✔ Downloaded and extracted project files.

🧶 Using Yarn to install packages. You can pass --npm to use npm instead.

✔ Installed JavaScript dependencies.

✅ Your project is ready!

To run your project, navigate to the directory and run one of the following yarn commands.

- cd react-native-sample
- yarn start # you can open iOS, Android, or web from here, or run them directly with the commands below.
- yarn android
- yarn ios
- yarn web

$ yarn start
yarn run v1.22.10
$ expo start
Starting project at /Users/matsumoto/Documents/MyWork/react-native-sample
Expo DevTools is running at http://localhost:19002
Opening DevTools in the browser... (press shift-d to disable)
Starting Metro Bundler

 exp://192.168.XX.XX:19000
~QR割愛~
 To run the app with live reloading, choose one of:
 › Scan the QR code above with the Expo app (Android) or the Camera app (iOS).
 › Press a for Android emulator, or i for iOS simulator, or w to run on web.
 › Press e to send a link to your phone with email.

expoをインストールしてQRを読み込む

QRを読み込むと以下のような画面が出力される。
image.png

NativeBaseを導入する

UIライブラリNativeBaseを導入する

install

$ yarn add native-base

# NativeBase は Font.loadAsync を使ってロードできるカスタムフォントをいくつか使用しているため、インストールが必要
$ expo install expo-font

ファイルの修正

useCachedResources.tsファイルにてフォントの読み込みを行う。

useCachedResources.ts
import { Ionicons } from '@expo/vector-icons';
import * as Font from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import * as React from 'react';

export default function useCachedResources() {
  const [isLoadingComplete, setLoadingComplete] = React.useState(false);

  // Load any resources or data that we need prior to rendering the app
  React.useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHideAsync();

        // Load fonts
        await Font.loadAsync({
          Roboto: require("native-base/Fonts/Roboto.ttf"),
          Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
          ...Ionicons.font,
          "space-mono": require("../assets/fonts/SpaceMono-Regular.ttf"),
        });
      } catch (e) {
        // We might want to provide this error information to an error reporting service
        console.warn(e);
      } finally {
        setLoadingComplete(true);
        SplashScreen.hideAsync();
      }
    }

    loadResourcesAndDataAsync();
  }, []);

  return isLoadingComplete;
}

EditScreenInfo.tsを修正してNativeBaseのボタンを表示してみる

EditScreenInfo.ts
import React from 'react';

import { Container, Text, Button } from "native-base";

export default function EditScreenInfo({ path }: { path: string }) {
  return (
    <Container>
      <Button>
        <Text>start working on your app!</Text>
      </Button>
    </Container>
  );
}

画面確認

導入できた。
image.png

why-did-you-render導入

install

$ yarn add @welldone-software/why-did-you-render

setting

wdyr.tsをプロジェクトルートに作成

wdyr.ts
import React from "react";
import whyDidYouRender from "@welldone-software/why-did-you-render";
if (process.env.NODE_ENV === "development") {
  whyDidYouRender(React, {
    trackAllPureComponents: true,
  });
}

App.tsxを修正

App.tsx
import './wdyr'

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';

import useCachedResources from './hooks/useCachedResources';
import useColorScheme from './hooks/useColorScheme';
import Navigation from './navigation';

export default function App() {
  const isLoadingComplete = useCachedResources();
  const colorScheme = useColorScheme();

  if (!isLoadingComplete) {
    return null;
  } else {
    return (
      <SafeAreaProvider>
        <Navigation colorScheme={colorScheme} />
        <StatusBar />
      </SafeAreaProvider>
    );
  }
}

レンダリングされた理由のログを確認

導入はできた。

image.png

eslint導入

install

$ yarn add eslint
$ yarn add eslint-plugin-react @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-react-hooks

setting

初期設定を行う

$ ./node_modules/.bin/eslint --init
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
✔ How would you like to define a style for your project? · guide
✔ Which style guide do you want to follow? · airbnb
✔ What format do you want your config file to be in? · JSON
~割愛~
✔ Would you like to install them now with npm? · No / Yes
~割愛~

eslintの設定を行う

eslintrc.json
{
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "airbnb",
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:@typescript-eslint/recommended-requiring-type-checking"

    ],
    "settings": {
        "import/resolver": {
            "node": {
                "extensions": [
                    ".js",
                    ".jsx",
                    ".ts",
                    ".tsx",
                    ".json",
                    ".native.js"
                ]
            }
        }
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "./tsconfig.json",
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "ignorePatterns": ["node_modules/"],
    "rules": {
        "import/extensions": [
            "error",
            "ignorePackages",
            {
                "js": "never",
                "jsx": "never",
                "ts": "never",
                "tsx": "never"
            }
        ],
        "no-use-before-define": "off",
        "@typescript-eslint/no-use-before-define": [
            "off"
        ],
        "react/jsx-filename-extension": [
            2,
            { 
                "extensions": [".js", ".jsx", ".ts", ".tsx"]
            }
        ],
        "react/jsx-props-no-spreading":"off",
        "@typescript-eslint/explicit-module-boundary-types":"off",
        "react/destructuring-assignment":"off",
        "react/display-name":"off",
        "react/prop-types":"off",
        "react/no-unescaped-entities":"off"
    }
}

参考

https://github.com/software-mansion/react-native-screens/issues/62
https://stackoverflow.com/questions/55614983/jsx-not-allowed-in-files-with-extension-tsxeslintreact-jsx-filename-extensio

eslint --fixを実行する

package.jsonscriptsに以下を追加

package.json
  "scripts": {
    ...
    "lint": "eslint --ext .ts,.tsx ./"
  },

実行する

$ yarn lint --fix

エラーがいっぱい出るので修正する。

ここまでの内容をGithubで。

所感

アプリで作りたいものができたらこれを利用する。
意外とすんなりできた感ある。

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
2