React Nativeで動的にナビゲーションヘッダー文言を設定する方法

実現コード const navigation = useNavigation(); useLayoutEffect(() => { if (response && navigation) { navigation.setOptions({ title: `${response}`, }); } }, [navigation, response]); useLayoutEffectって? 実装していて、useLayoutEffectっていうhooksが聞き覚えなさ過ぎて、react native専用のhooksだと思っていたけど、調べるとreactが用意しているhooksらしい。 useLayoutEffect useLayoutEffect は useEffect の一種ですが、ブラウザが画面を再描画する前に実行されます。 とのことで、さらに、 useLayoutEffect はパフォーマンスを低下させる可能性があります。可能な限り useEffect を使用することを推奨します。 とのことだった。できる限り使わないでほしいとのことなので知らなくても無理はなかったかもしれない。 今回は、useLayoutEffectを使用することで、タイトルが描画される前に処理が実行されるため、新しいタイトルが即座に反映されるようになっている。 ただこのコードだと、responseが取得されるまでは元のタイトルが表示されるので、responseがfalseの時の条件を付与する必要があるということにいまさら気が付いた。

投稿日 · 2025-01-16 · 更新日 · 2025-01-16 · 1 分 · nove-b

React Nativeで無限スクロールのタイムラインを作成した

Mastodonのクライアントアプリを作るうえで最もコアな機能であるタイムラインを作成した。 無限スクロールを実装するためにいろいろと調べたりしたのでまとめておく。 FlatListが優秀 FlatList 完全なクロスプラットフォーム。 オプションの水平モード。 設定可能なビューアビリティ コールバック。 ヘッダーのサポート。 フッターのサポート。 セパレーターのサポート。 引っ張って更新します。 スクロールの読み込み。 ScrollToIndex のサポート。 複数列のサポート。 という多くの機能をサポートしているリストコンポーネント。 今回はタイムラインの無限スクロールを実現したいということで、 リストを引っ張り更新 リストのそこについたら再フェッチ 上記2つが実現できればいい。 そしてその2つはFlatListに標準搭載されている。 リストを引っ張り更新 onRefresh というPropsが用意されている。 このイベントで最新情報を取得し、useStateを更新すればいい。 リストのそこについたら再フェッチで無限スクロール onEndReachedという Propsが用意されている。 このイベントで最新情報を取得し、useStateを更新すればいい。 その際スクロールのタイミングで重複のデータがsetされることがあった。 重複チェックをすることで解決した。 またonEndReachedThresholdというPropsを使った。 onEndReachedThreshold: 0 ~ 1の間の数値でどのくらいの距離でonEndReachedを呼び出すかを決められます。0が一番近くで、1が一番遠いです。 という記事を参照したのだけれど、公式のPropsには明記されていなかった。 機能しているかを確認する必要がある。 ##その他、実装した機能 ボトムメニューのタブクリックでFlatListのトップにスクロールする const flatListRef = useRef<FlatList<Interface>>(null); レンダリング時にドムを取得しておき、タブクリックで書きイベントを発火させる。 if (flatListRef.current) { flatListRef.current.scrollToOffset({ animated: true, offset: 0 }); } スクロールバーを非表示にする showsVerticalScrollIndicatorというPropsをfalseにする。 まだ実装していないけど試したい機能 List~~~Componentを活用する ListEmptyComponent ListFooterComponent ListHeaderComponent 特にListFooterComponentは無限スクロール時の読み込みに使えそうなのでUI改善で使っていきたい。 たぶんこれくらい。 使ったPropsは以下の通り。 ref={flatListRef} data={timeline} keyExtractor={(item) => item....

投稿日 · 2025-01-11 · 更新日 · 2025-01-11 · 1 分 · nove-b

ExpoとReact Nativeで作成したアプリのAPKを作成する

作成中のマストドンクライアントアプリの1つの機能が完成したので実機で活用したいという思いが生まれ、apkを作成することにした。 最初のビルドを作成するを参考にして進めていき、無事にapkを作成することに成功した。 EAS CLIをインストール ドキュメントが充実しているので、問題なくできるだろうと踏んでいたのだが、最初で壁にぶつかった。 npm install -g eas-cli というコマンドでEAS CLIをインストールするのだが、なぜうまくインストールされない。 なんかVoltaの権限でうまく入らなかったので、 "C:\\Program Files\\Volta\\npm.exe" install -g eas-cli を管理者権限で実行したら成功した。 C:\Windows\System32>eas --version eas-cli/14.2.0 win32-x64 node-v20.15.0 npm install -g eas-cli npm install -g eas-cliではシステムのPATHにあるデフォルトのnpmを使うけど、"C:\\Program Files\\Volta\\npm.exe" install -g eas-cliはVoltaで管理しているnpmを使用するという違いがあるらしい。 ログインする PS C:\dev\appname> eas login Log in to EAS with email or username (exit and run eas login --help to see other login options) √ Email or username ... email √ Password ... ******** Logged in プロジェクトを構成する AS Build 用に Android または iOS プロジェクトを構成するためにコマンドを実行する。...

投稿日 · 2024-12-28 · 更新日 · 2024-12-28 · 4 分 · nove-b

React NativeでMastodon認証を実装した

Mastodonnのクラインアント用ネイティブアプリをReact NativeとExpoで作成している。 バージョンは下記の通り。 "expo": "~52.0.11", "react-native": "0.76.3", 実装自体はできたんだけれど、正直いろいろと理解が足りていないので、整理してみる。 インストールしたPackage "expo-auth-session": "^6.0.1", "expo-secure-store": "^14.0.0" expo-auth-session ブラウザベースの認証を処理するための API 最初は認証時にWebViewを開いて認証に成功したらリダイレクトURIを用いてアプリ画面に戻すという仕組みを実装しようとしたんだけれど、そもそもリダイレクトURIがわからない。Expoの開発用URLを指定してみたけど、 java.io.IOException: Remote update request not successful という謎のエラーが出てアプリ側に戻らない。 そしてタスク管理でアプリに戻ると認証が成功しているという謎の現象が発生した。 色々悩んでいたけどexpo-auth-session を使用したらリダイレクトURIの作成をいい感じにやってくれた。 Expo AuthSessionにはexpo-crypto と一緒にインストールする必要があるって書いてあったけど、インストールしていない。今のところ問題はないので気にしないでおく。 expo-secure-store Expo SecureStore Expo用のローカルストレージ。 // 保存 await SecureStore.setItemAsync("key", value); // 参照 await SecureStore.getItemAsync("key"); // 削除 await SecureStore.deleteItemAsync("kye"); で、一通りの作業ができる。 認証に用いたMastodon API ${instanceUrl}/api/v1/apps クライアント アプリケーションを登録 ${instanceUrl}/oauth/authorize? OAuth トークンを生成および管理 ${instanceUrl}/oauth/token API 呼び出し中に使用するアクセス トークンを取得 認証までのフロー アプリケーションを登録 クライアント アプリケーションを登録APIを叩く。 Bodyにclient_name、redirect_uris、scopes、websiteが必要になる。 client_nameはアプリ名を指定し、redirect_urisはexpo-auth-sessionを使用し作成する。 redirect_uris: AuthSession.makeRedirectUri({ native: "{APPNAME}://redirect", }), scopesは権限を指定し、websiteはアプリのウェブサイトをインプットする。...

投稿日 · 2024-12-20 · 更新日 · 2024-12-20 · 1 分 · nove-b

Expoアプリの+not-found.tsxファイルの正体と「+」の意味

Expoでreact nativeのアプリを作成する時、インストール時のディレクトリ構成で+not-found.tsxとかいう謎のファイルがあった。たぶんというか確実に404ページではあるんだろうけれど、+が付いている。 Expoアプリのファイルにある「+」の意味 Not found routesのように公式には、 Expo Router は、404 のルートを処理するために使用される特別なファイル+not-found.tsxを提供します。このルート ファイルは、ネストされたレベルからのすべての一致しないルートと一致します。 一致しないルートとは、アプリのルーティング構成で定義されていないURLやパスにユーザーがアクセスした場合、そのアクセスに対応するページが見つからない状態のことを言うらしい。 つまり+は404ページのためにあるようなものと言っても過言じゃない? 過言かもしれないけれど、今はその理解で満足することにする。

投稿日 · 2024-12-07 · 更新日 · 2024-12-07 · 1 分 · nove-b