Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@ Axios를 사용하여 서버와 비동기통신하는 방법을 배웁니다.

<br/>

## 💡 과제 설명

- 이번 세션에서 배운 Axios를 활용하여 서버와 비동기 통신을 구현하는 과제입니다.
- REST API 중 POST와 GET 메서드를 사용하여 데이터를 주고받아 보세요!


## 💡 구현 결과
<img src="./result.gif">

<br/>

Expand Down
10 changes: 0 additions & 10 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
Expand Down
Binary file removed public/logo192.png
Binary file not shown.
Binary file removed public/logo512.png
Binary file not shown.
25 changes: 0 additions & 25 deletions public/manifest.json

This file was deleted.

Binary file added result.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BrowserRouter as Router, Routes, Route, Link} from "react-router-dom";

import UserList from "./components/UserList";
import LoginPage from "./components/LoginPage"

Expand All @@ -9,7 +8,6 @@ function App() {
<Routes>
<Route path="/" element={<LoginPage />} />
<Route path="/userlist" element={<UserList />} />

</Routes>
</Router>
);
Expand Down
60 changes: 38 additions & 22 deletions src/components/LoginPage.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
import React, { useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import "../styles/LoginPage.css";
import React, { useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import "../styles/LoginPage.css";

function LoginForm() {

function LoginForm() {
const[email, setEmail] = useState("");
const[password, setPassword] = useState("");
const navigate = useNavigate();

const handleLogin = async (e) => {
e.preventDefault();
const handleLogin = async (e) => {
e.preventDefault();
try{
const data = await axios.post(
"https://reqres.in/api/login",{
email,password},
{
headers: {
"x-api-key": "reqres-free-v1"
}
}
);
localStorage.setItem("email",email);
localStorage.setItem("token",data.data.token);

navigate("/UserList");
}catch(e){
const em = e.response?.data?.error
console.log(em);
}
};
return (
<form onSubmit={handleLogin} className="login-container">
<h2>🔐 로그인</h2>
<input type="email" placeholder="이메일" value={email} required onChange={(e)=>setEmail(e.target.value)}/>
<input type="password" placeholder="비밀번호" value={password} required onChange={(e)=>setPassword(e.target.value)}/>
<button type="submit">로그인</button>
</form>
);
}


};

return (
<form onSubmit={handleLogin} className="login-container">
<h2>🔐 로그인</h2>
<input/>
<input/>
<button type="submit">로그인</button>
</form>
);
}

export default LoginForm;
export default LoginForm;
41 changes: 38 additions & 3 deletions src/components/UserList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,57 @@ import axios from "axios";
import "../styles/UserList.css";

function UserList() {
const [users,setUsers] = useState([]);
const [keyword,setKeyword] = useState("");

useEffect(()=>{

const fetch = async ()=>{
try{
const ag = await axios.get(
"https://reqres.in/api/users?page=2",
{
headers:{
"x-api-key": "reqres-free-v1"
}
}
);
setUsers(ag.data.data);
}catch(e){
console.log(e);
}
}
fetch();
},[]);

const search = users.filter((u)=>{
const info = `${u.first_name}${u.last_name}<br>${u.email}`;
return info.includes(keyword);
})
return (
<div className="user-container">
<div className="user-info-box">
<p><strong>이메일:</strong> { }</p>
<p><strong>토큰:</strong> { }</p>
<p><strong>이메일:</strong>{localStorage.getItem('email')}</p>
<p><strong>토큰:</strong> {localStorage.getItem('token')}</p>
</div>

<h2 className="user-title">👥 유저 목록</h2>

<input
className="user-search"
placeholder="이름 또는 이메일로 검색하세요"
value={keyword}
onChange={(e)=>{setKeyword(e.target.value)}}
/>

<div className="user-list">

{search.length?search.map((u)=>(
<div className="user-card">
<img className="user-avatar" src={u.avatar} alt="img"/>
<p>{u.first_name} {u.last_name}</p>
<p className="user-email">{u.email}</p>
</div>
)):<div>검색 결과가 없습니다.</div>}
</div>
</div>
);
Expand Down