import './App.css';
import { UserCard } from './components/UserCard';
import { User } from './types/api/user';
import { useState } from 'react';
import { UserProfile } from './types/userProfile';
import axios from 'axios';
export default function App() {
const [userProfiles, setUserProfiles] = useState<Array<UserProfile>>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const onClickFetchUser = () => {
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(() => {
// catch: データを取得出来なかった場合に呼ばれる。
setError(true);
})
.finally(() => {
// finally: なにが起きてもaxiosの実行完了後に呼ばれる。
setLoading(false);
});
};
return (
<div className="App">
<button onClick={onClickFetchUser}>データ取得</button>
<br />
{error ? (
<p style=>データの取得に失敗しました。</p>
) : loading ? (
<p>Loading...</p>
) : (
<>
{userProfiles.map((user) => (
<UserCard key={user.id} user={user} />
))}
</>
)}
</div>
);
}
import { UserProfile } from '../types/userProfile';
import { FC } from 'react';
type Props = {
user: UserProfile;
};
export const UserCard: FC<Props> = (props) => {
const { user } = props;
const style = {
border: 'solid 1px #ccc',
borderRadius: '8px',
padding: '0 16px',
margin: '8px',
};
return (
<div style={style}>
<dl>
<dt>名前</dt>
<dd>{user.name}</dd>
<dt>メール</dt>
<dd>{user.email}</dd>
<dt>住所</dt>
<dd>{user.address}</dd>
</dl>
</div>
);
};
export type User = {
id: number;
name: string;
username: string;
email: string;
address: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string
}
phone: string;
website: string;
company: {
name: string;
catchPhrase: string;
bs: string
}
}
export type UserProfile = {
id: number;
name: string;
email: string;
address: string;
};