【ITニュース解説】Smooth Animated Progress Bar in React Native

2025年09月04日に「Dev.to」が公開したITニュース「Smooth Animated Progress Bar in React Native」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

スマホアプリ開発のReact Nativeで、進捗を示すプログレスバーの実装方法を解説。Animated APIを使い、進捗に合わせてバーが滑らかに伸びるアニメーションを実現する手順が紹介されている。

出典: Smooth Animated Progress Bar in React Native | Dev.to公開日:

ITニュース解説

スマートフォンアプリ開発において、ユーザーに処理の進捗状況を視覚的に伝えるプログレスバーは、ユーザー体験を向上させるために不可欠なUIコンポーネントである。特に、進捗が滑らかなアニメーションで表現されると、アプリ全体の品質感が高まり、ユーザーは待ち時間を快適に感じやすくなる。ここでは、人気のクロスプラットフォーム開発フレームワークであるReact Nativeを用いて、スムーズなアニメーションを伴うプログレスバーを実装する方法について解説する。

この実装の核となる技術は、React Native向けの高機能アニメーションライブラリ「react-native-reanimated」である。React Nativeには標準のAnimated APIも存在するが、reanimatedはより複雑なアニメーションを高いパフォーマンスで実現できるという利点がある。その理由は、アニメーションの計算をUIスレッドで直接実行する点にある。通常、React Nativeの処理はJavaScriptスレッドで行われるが、このスレッドが他の処理で混み合っているとアニメーションがカクつく原因となる。reanimatedは、アニメーション処理をUI描画専用のUIスレッドに分離することで、JavaScriptスレッドの負荷に関わらず、常に滑らかな動きを保証するのである。

プログレスバーの基本的な構造は非常にシンプルで、通常は二つのコンポーネントから構成される。一つはプログレスバーの背景となる外枠のコンテナで、もう一つはその内側で実際の進捗を示すバーである。これらはReact Nativeの基本的なUI要素であるViewコンポーネントを使用して作成する。アニメーションを適用するのは、この内側のバーの幅(width)である。

アニメーションを実現するために、reanimatedが提供するいくつかの重要な機能(フック)を利用する。まず「useSharedValue」は、アニメーションで変化させたい値を保持するための特別な変数を作成するフックだ。この値はUIスreadとJavaScriptスレッド間で効率的に共有されるため、パフォーマンスの低下を引き起こさない。今回は、プログレスバーの幅をこのuseSharedValueで管理する。

次に「useAnimatedStyle」は、useSharedValueで保持している値に基づいて、コンポーネントのスタイルを動的に生成するためのフックである。例えば、useSharedValueで管理している幅の値が変化すると、このフックが自動的にその変化を検知し、対応するコンポーネントのスタイル(CSSのwidthプロパティなど)をリアルタイムで更新する。これにより、値の変更が画面上の見た目の変化として反映される。

そして、滑らかなアニメーションの鍵を握るのが「withTiming」関数だ。この関数は、useSharedValueの値をある目標値まで、指定した時間(duration)をかけて徐々に変化させる役割を担う。単に値を瞬時に変更するのではなく、例えば「0.5秒かけて現在の幅から目標の幅まで滑らかに変化させる」といった指示を与えることができる。このwithTimingを使うことで、プログレスバーがカクカクとではなく、スムーズに伸縮する動きが実現される。

具体的な実装の流れとしては、まず外部から進捗度(0から1の間の数値)をprogressというプロパティで受け取るProgressBarコンポーネントを作成する。コンポーネント内では、useSharedValueを使ってアニメーションさせる幅の値を初期化する。そして、useAnimatedStyleを用いて、この共有値と内側のバーのwidthスタイルを連動させる。

進捗度が変化したタイミングでアニメーションを開始するためには、Reactの標準フックであるuseEffectを使用する。このフックは、監視対象のprogressプロパティが変更されたときに特定の処理を実行するよう設定できる。progressの値が変わると、useEffectの内部でwithTiming関数を呼び出し、useSharedValueで管理している幅の値を更新する。このとき、目標となる幅は「プログレスバー全体の幅 × progressの値」として計算される。コンポーネントが画面に描画された際の実際の幅は、onLayoutイベントを通じて取得できるため、デバイスの画面サイズに依存しない柔軟な実装が可能だ。

このように、react-native-reanimateduseSharedValueuseAnimatedStylewithTimingといった機能を組み合わせることで、パフォーマンスが高く、見た目にも美しいアニメーション付きプログレスバーを効率的に実装できる。これは、単にUI部品を作るだけでなく、アプリケーションのUXを向上させるための重要な技術であり、システムエンジニアを目指す初心者にとっても、宣言的なUIプログラミングとアニメーションの連携を学ぶ上で非常に有益な実践例となるだろう。