ReactのカスタムHookを使ってみる
一応状態管理らしい
同じファイルにuseStateを書き過ぎるとコードが増えすぎてしまう!
この辺は、FlutterのStatefulWidgetに似てる気がします。できるだけUIとロジックは分離したいので、オブジェクト思考プログラミングらしくするために、ファイルを分けて、APIからデータが取得できるか試してみました。
✅元のコード
なんだか冗長なコードですね。長いって意味ですね。僕は国語が弱いので、知りませんでした😅
import { useState, useEffect } from "react";
function App() {
// データの型を定義するinterfaceを作成
interface Data {
id: number;
name: string;
}
// Data型の配列を作成
const [data, setData] = useState<Data[]>([]);
// JSONPlaceholderからデータを取得する関数
const getData = async () => {
// JSONPlaceholderからデータを取得
const response = await fetch("https://jsonplaceholder.typicode.com/users");
// 取得したデータをJSON形式に変換
const data = await response.json();
// 変換したデータを変数に格納
setData(data);
};
// コンポーネントがマウントされた時に実行する関数
// マウントとは、コンポーネントがDOMに追加されること
// アンマウントは、コンポーネントがDOMから削除されること
useEffect(() => {
getData();
}, []);// []は第二引数で、空の配列を渡すことで、コンポーネントがマウントされた時のみ実行されるようになる
// 取得したデータを表示する
return (
<>
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</>
);
}
export default App;
🔧リファクタリングしてみる
Udemy何度もやったのに、Reactのロジックを分けるところが理解できませんでした!
なので、ChatGPTくんに手伝ってもらいました!
🤖ChatGPT
状態管理とファイルの分離を実現するために、以下のステップに従ってコードをリファクタリングします。
状態管理のためのカスタムフックを作成します。
ロジック部分を別のファイルに分離します。
画面部分を別のファイルに分離します。
まず、状態管理のためのカスタムフックを作成しましょう。useDataという名前のカスタムフックを作成し、状態とデータの取得関数を含めます。
import { useState, useEffect } from "react";
interface Data {
id: number;
name: string;
}
const useData = () => {
const [data, setData] = useState<Data[]>([]);
const getData = async () => {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
setData(data);
};
useEffect(() => {
getData();
}, []);
return { data };
};
export default useData;
次に、ロジック部分を別のファイルに分離します。useDataカスタムフックを使用してデータを取得し、AppLogicという名前のファイルにロジックを移動します。
import useData from "./useData";
const AppLogic = () => {
const { data } = useData();
return { data };
};
export default AppLogic;
最後に、画面部分を別のファイルに分離します。AppコンポーネントをAppScreenという名前のファイルに移動します。
import AppLogic from "./AppLogic";
const AppScreen = () => {
const { data } = AppLogic();
return (
<>
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</>
);
};
export default AppScreen;
これで、状態管理と画面ロジックが別々のファイルに分離されました。元のコードではAppコンポーネントでしたが、これをAppScreenという名前に変更しました。そして、新しいAppコンポーネントを作成して、AppScreenを含めます。
import AppScreen from "./AppScreen";
function App() {
return <AppScreen />;
}
export default App;
このようにリファクタリングすることで、状態管理と画面のロジックが分離され、コードがよりモジュール化された状態になります。
スクリーンショット
状態管理のパッケージについて質問してみた
はい、RecoilやReduxなどの外部の状態管理ライブラリを使用せずに、状態管理を実装することも可能です。ReactのHooksを使用することで、状態を管理するためのローカルなステートを作成できます。
ReactのHooksには、useStateやuseReducerなどの関数があります。これらの関数を使用することで、コンポーネント内で状態を保持し、更新することができます。
このように、Hooksを使用することで、コンポーネント内で状態を管理することができます。このアプローチは、小規模なアプリケーションや状態が単純な場合に特に有用です。ただし、アプリケーションが複雑化し、複数のコンポーネント間で状態を共有する必要がある場合は、外部の状態管理ライブラリ(例:Recoil、Redux)の使用を検討することが一般的です。これらのライブラリは、状態の中央管理やデータフローの制御など、より高度な機能を提供します。
まとめ
やはり、Riverpodみたいに状態管理のパッケージを使うのが他の言語でも当然みたいですね。使ってないところもあるらしいですが?
ChatGPT3.5を使えば、ReactとTypeScriptのキャッチアップは、早くできるかもしれません?
私の師匠は、C++を早くキャッチアップしたらしい?
Discussion