import axios from "axios";
import { useState } from "react";
import { UserProfile } from "../types/userProfile";
import { User } from "../types/api/user";
// 全ユーザー一覧を取得するカスタムフック
export const useAllUsers = () => {
const [userProfiles, setUserProfiles] = useState<Array<UserProfile>>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const getUsers = () => {
setLoading(true);
setError(false);
axios
.get<Array<User>>("https://jsonplaceholder.typicode.com/users")
.then((res) => {
const data = res.data.map((user) => ({
id: user.id,
name: `${user.name}(${user.username})`,
email: user.email,
address: `${user.address.city}${user.address.suite}${user.address.street}`
}));
setUserProfiles(data);
})
.catch((err) => {
setError(true);
})
.finally(() => {
setLoading(false);
});
};
// 他のコンポーネントでカスタムフックで定義したStateや関数が使用できるように、returnで返却する
return { getUsers, userProfiles, loading, error };
};
import "./styles.css";
import { UserCard } from "./components/UserCard";
import { useAllUsers } from "./hooks/useAllUsers";
export default function App() {
// カスタムフックを呼び出し、返却値を受け取る
const { getUsers, userProfiles, loading, error } = useAllUsers();
const onClickFetchUser = () => getUsers();
return (
<div className="App">
<button onClick={onClickFetchUser}>データ取得</button>
<br />
{error ? (
<p style={{ color: "red" }}>データの取得に失敗しました</p>
) : loading ? (
<p>Loading...</p>
) : (
<>
{userProfiles.map((user) => (
<UserCard key={user.id} user={user} />
))}
</>
)}
</div>
);
}
カスタムフックはhooksというディレクトリを切って管理していくのが一般的である。
他のコンポーネントでカスタムフックで定義したStateや関数が使用できるように、returnで返却する。
カスタムフックで呼び出したStateはそれぞれのコンポーネントで独立扱いなので、コンポーネント間でStateは競合しない。