React Native学習日記
環境構築してみる
下記を参考にする
二つの開発ツールがある
- React Native CLI
- 以前挫折した(環境構築)
- 最初はこっちの方がおすすめらしいので環境構築してみる
- React Native Expo
- ちょっと触ったことあるけどお手軽な印象
React Native CLIの環境構築
HomeBrewを使ってインストールしようとするが、HomeBrewがない
HomeBrewのインストール
下記を参考にする。
インストールコマンドを実行。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Homebrew is not (yet) supported on ARM processors!
Rerun the Homebrew installer under Rosetta 2.
If you really know what you are doing and are prepared for a very broken
experience you can use another installation option for installing on ARM:
https://docs.brew.sh/Installation
HomeBrewをインストールするにも問題がある模様、調査してみる
Macの世代によって上記のコマンドが使えないだとかなんとか(適当)
terminalについて、Rosettaを使用して開く、という風な設定を行う。
FinderからTerminalを検索⇨右クリック⇨情報を見る
で、「Rosettaを使用して開く」にチェック。
その後Terminalを再起動し、HomeBrewのインストールコマンドを再度実行。
無事にインストールできたので、再度ReactNative CLIのインストール。
$ brew install node
$ brew install watchman
CocoaPodsとやらもインストール
$ sudo gem install cocoapods
iOSシミュレータも無事起動したので、ReactNativeプロジェクトを立ち上げてみる
npx react-native init AwesomeProject
下記のエラー。。。
Error: Failed to install CocoaPods dependencies for iOS project, which is required by this template.
なんやかんやエラー内容を調査し下記リンクが関係しそうなので対応。
pod installを実行。
ようやくiOSプロジェクトを起動しようとしたが下記のエラー。
Failed to construct transformer: DuplicateError: Duplicated files or mocks. Please check the console for more info
...なんか色々うまくいかないので一旦AwesomeProjectを削除
rm -rf AwesomeProject
node,watchmanのインストールは出来てるので、下記参考に進めたらようやくiOSプロジェクトが起動できた。
Udemy講座体験記
ニュースアプリを作りながら学べるUdemyの講座を受講
簡単な流れは下記(実施した範囲だけ)
- Expoのインストール
- 実機のアプリデバッグ
- Expoのメリット・デメリットについて
- UI作成
- コンポーネント化
- APIコール
- Class Component / Function Component の説明
- 画面遷移
技術的に掘り下げたいところ
- Expo / CLIの違い、メリットデメリット
- Class Component / Function Componentの違い
- どちらかというと Reactの内容
UI作成
<View style={styles.container}>
<View style={styles.itemContainer}>
<View style={styles.leftContainer} />
<View style={styles.rightContainer} />
</View>
</View>
- <div>の代わりに<View>で区切る
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
itemContainer: {
height: 100,
width: '100%',
borderColor: 'gray',
borderWidth: 1,
flexDirection: 'row',
},
leftContainer: {
width: 100,
},
rightContainer: {
flex: 1,
padding: 10,
justifyContent: 'space-between',
},
text: {
fontSize: 16,
},
subText: {
fontSize: 12,
color: 'gray',
},
});
- flexDirection で向きを設定する
-
flexDirection: "column"
でコンポーネントが縦に並ぶ -
flexDirection: "row"
で横に並ぶ- デフォルトは
column
- デフォルトは
-
<Text numberOfLines={3}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation
</Text>
<Text>ReactNews</Text>
- numberOfLines
- 表示する行数を指定できる
- 行数を超える場合は「...」で省略してくれる
styles関連
- alignItems
-
flex-start
向きに対してスタート地点から始まる -
flex-end
向きに対して終点に接地する-
flexDirection
で指定した向きによって配置が決まる
-
-
- justifyContent
- flexDirectionで指定した向きに対して縦方向に位置調整が出来る
-
space-between
均等な間を確保する -
space-around
コンポーネントの外側の余白も設ける
コンポーネント化
- Reactとほぼ変わらない
APIコール
useState
- Function ComponentのHooksを利用
- state等のReactの機能をクラスを書かずに使えるようになる
- ReactNative 0.59以降でサポート
- React Expo SDK33以降で対応
const [cont,setCount] = useState(0);
-
count
でstateの値を保持 -
setCount
stateの値を更新するメソッド - 引数(0)はcountの初期値を表す
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
const subscription = props.source.subscribe();
return () => {
// Clean up the subscription
subscription.unsubscribe();
};
});
- レンダーのタイミングで関数が実行される
useEffect(
() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
},
[props.source],
);
- 条件付き副作用
- 第2引数の値が変更したタイミングでuseEffectの中の関数を実行する(第1引数)
- 2つ目の引数に空の配列を渡すとマウント時に実行され、アンマウント時にクリーンアップされる
- 更新時(画面の再描画)には実行されないようになる
axios
axiosとは
- REST API等を叩くときに使う
セットアップ
npm install axios
axiosをインストールしておく
import axios from 'axios';
axiosをインポート
const fetchArticles = async () => {
try {
const response = await axios.get(URL);
setArticles(response.data.articles);
} catch (error) {
console.error(error);
}
};
APIコールでニュース記事を取得
画面遷移
Reduxによるクリップ管理
Reduxとは
状態の集中管理
- store
- 状態を集中管理する場所
- reducer
- storeを更新する役目を担う
- 前回のstateとActionを受け取って新しいstateをリターンする関数
- action
- type
- Actionの種類を識別するための予め定義された文字列
- payload
- 実行する際に使われる任意のデータ
- type
ActionがDispatch(送信)されると、Storeから渡されたOldStateとActionから渡されたPayloadを元に新たなNewStateを生成する
実装
必要なパッケージのインストール
npm install redux react-redux
Actionの追加
今回追加するAction
- ADD_CLIP
- クリップを追加する
- DELETE_CLIP
- クリップを削除する
手順
- store/actionsフォルダを作成
- store/actions内にuser.jsを追加
- ADD_CLIPとDELETE_CLIPの追加
export const addClip = ({clip}) =>{
return{
type: 'ADD_CLIP',
clip,
};
};
export const deleteClip = ({clip}) =>{
return{
type: 'DELETE_CLIP',
clip,
};
};
Reducerの追加
- store/reducersフォルダを作成
- store.reducers内にuser.jsを追加
const initialState = {
clips: [],
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "ADD_CLIP":
return {
...state,
clips:[...state.clips,action.clip]
};
case "DELETE_CLIP":
return {
...state,
clips:state.clips.filter(clip => clip.url !== action.clip.url),
};
default:
return state;
}
};
export default reducer;
Storeの追加
Storeは、巨大なjsonツリーのようなイメージ。
- store
- user
- clipse[]
- user
- clips
- ...
- user
Storeの作成
- store/index.jsの作成
- ツリー構造を作るため、combineReducersのimport
- 作成したuserReducerを配置する
- ルートのReducerを定義する
- createStoreのimportが必要
import { createStore, combineReducers } from "redux";
import userReducer from "./reducers/user";
const rootReducer = combineReducers({
user: userReducer,
});
const store = createStore(rootReducer);
export default store;
- アプリケーションでstoreを使うためにApp.jsでの呼び出し、定義
- Providerとstoreのimport
- AppNavigatorをProviderで囲む
import React from "react";
import AppNavigator from "./navigation/AppNavigator";
import { Provider } from "react-redux";
import store from "./store";
export default App = () => {
return (
<Provider store={store}>
<AppNavigator />
</Provider>
);
};
Expo と CLIの比較
簡単に調査してみる
React Native CLI
メリット
- Java/Objective-c で記述されたネイティブモジュールを追加できる
デメリット
- Android Studio / Xcodeが必要
- iOS開発にMacが必須
- 実機デバッグにはUSB接続が必要
- アプリ配布には.apk/.ipaファイルを全体に送信する必要がある
- Push通知やAssetManager等、手動でインストールしてnpmとリンクさせる必要がある(?)
- プロジェクト設定、デバイス構成等が複雑で手間がかかる
React Native Expo
メリット
- 設定が簡単、数分で完了
- アプリの配布が簡単。QRコードやリンクで開ける
- アプリの実行にビルドが必要ない
- 標準プロジェクトに基本的なライブラリが揃っている(Push通知、AssetManager等)
- .apk/.ipaファイルを作成できる(ストア配布が簡単?)
デメリット
- ネイティブモジュールの追加が出来ない
- Java/Objective-Cのネイティブコードを使用するライブラリは使えない
- ExpoKit? が色々デメリットを抱えている(要調査)
比較結果
Expoはお手軽だが、細かいネイティブ機能が扱いづらい。
セットアップやメンテが大変な分、最新のネイティブ機能を扱えるのがReact Native CLIから構築する場合となる。