diff --git a/package.json b/package.json
index 910845e..433b6af 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
+ "axios": "^0.24.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
diff --git a/src/App.css b/src/App.css
index 74b5e05..30026f2 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,38 +1,66 @@
.App {
text-align: center;
+ padding-top: 2rem;
}
-.App-logo {
- height: 40vmin;
- pointer-events: none;
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1040;
+ width: 100vw;
+ height: 100vh;
+ background-color: #000;
+ opacity: .5;
}
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
+.modal-wrapper {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1050;
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ outline: 0;
}
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
+.modal {
+ z-index: 100;
+ background: white;
+ position: relative;
+ margin: 1.75rem auto;
+ border-radius: 3px;
+ max-width: 500px;
+ padding: 2rem;
+}
+
+.modal-header {
display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
+ justify-content: flex-end;
}
-.App-link {
- color: #61dafb;
+.modal-close-button {
+ font-size: 1.4rem;
+ font-weight: 700;
+ line-height: 1;
+ color: #000;
+ opacity: .3;
+ cursor: pointer;
+ border: none;
}
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
+button {
+ font-size: .9rem;
+ font-weight: 700;
+ border: none;
+ border-radius: 3px;
+ padding: .3rem 1rem;
+ margin-left: .5rem;
}
+
+.button-default {
+ background: #247BA0;
+ color: #fff;
+}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index 3784575..23cffe1 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,25 +1,24 @@
-import logo from './logo.svg';
+import React,{useState,useEffect, useRef} from 'react';
+import ReactDOM from 'react-dom'
+import myAPI from './apis/myAPI';
import './App.css';
+import useAsync from './hooks/useAsync';
+
+
+const App = () => {
+ const [{data:employees,loading,error},fetchEmployee] = useAsync(myAPI);
+
+ useEffect(()=>{
+ fetchEmployee();
+ },[])
-function App() {
return (
-
+ {loading ?
Loading
:''}
+ {error ?
error!
: ''}
+ {employees?
{employees.map(employee=>{employee.name}
{employee.email}
)}
: ''}
);
-}
+};
-export default App;
+export default App;
\ No newline at end of file
diff --git a/src/App.test.js b/src/App.test.js
deleted file mode 100644
index 1f03afe..0000000
--- a/src/App.test.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
- render();
- const linkElement = screen.getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
-});
diff --git a/src/apis/myAPI.js b/src/apis/myAPI.js
new file mode 100644
index 0000000..f604897
--- /dev/null
+++ b/src/apis/myAPI.js
@@ -0,0 +1,17 @@
+const myAPI = ()=>{
+ return new Promise((resolve,reject)=>{
+ setTimeout(()=>{
+ resolve([{
+ id:1,
+ name:'SAM',
+ email:'korkt1.kim@samsung.com'
+ },{
+ id:2,
+ name:'SUNG',
+ email:'korkt2.kim@samsung.com'
+ }])
+ },2000)
+ })
+}
+
+export default myAPI;
\ No newline at end of file
diff --git a/src/hooks/useAsync.js b/src/hooks/useAsync.js
new file mode 100644
index 0000000..708ac5d
--- /dev/null
+++ b/src/hooks/useAsync.js
@@ -0,0 +1,38 @@
+import React,{useReducer} from 'react';
+
+const initialState ={
+ data:null,
+ loading:false,
+ error: null,
+}
+
+const reducer = (state,action) =>{
+ switch (action.type){
+ case 'LOADING':
+ return {...state,loading:true,error:null,data:null};
+ case 'SUCCESS':
+ return {...state,data:action.data,loading:false,error:null};
+ case 'ERROR' :
+ return {...state,data:null,loading:false,error:action.error}
+ default:
+ return {...state}
+ }
+}
+
+
+const useAsync = (callback) =>{
+ const [state,dispatch] = useReducer(reducer,initialState)
+ const fetchData = async () =>{
+ dispatch({type:'LOADING'});
+ try{
+ const data = await callback();
+ dispatch({type:'SUCCESS',data});
+ }catch(e){
+ dispatch({type:'ERROR',error:e});
+ }
+
+ }
+ return [state,fetchData];
+}
+
+export default useAsync
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index ef2edf8..6832e78 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,7 +2,6 @@ import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
-import reportWebVitals from './reportWebVitals';
ReactDOM.render(
@@ -10,8 +9,3 @@ ReactDOM.render(
,
document.getElementById('root')
);
-
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
diff --git a/src/logo.svg b/src/logo.svg
deleted file mode 100644
index 9dfc1c0..0000000
--- a/src/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js
deleted file mode 100644
index 5253d3a..0000000
--- a/src/reportWebVitals.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const reportWebVitals = onPerfEntry => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry);
- getFID(onPerfEntry);
- getFCP(onPerfEntry);
- getLCP(onPerfEntry);
- getTTFB(onPerfEntry);
- });
- }
-};
-
-export default reportWebVitals;
diff --git a/src/setupTests.js b/src/setupTests.js
deleted file mode 100644
index 8f2609b..0000000
--- a/src/setupTests.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
diff --git a/yarn.lock b/yarn.lock
index 5c7137e..d4582b2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2522,6 +2522,13 @@ axe-core@^4.0.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.2.tgz#7cf783331320098bfbef620df3b3c770147bc224"
integrity sha512-V+Nq70NxKhYt89ArVcaNL9FDryB3vQOd+BFXZIfO3RP6rwtj+2yqqqdHEkacutglPaZLkJeuXKCjCJDMGPtPqg==
+axios@^0.24.0:
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
+ integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
+ dependencies:
+ follow-redirects "^1.14.4"
+
axobject-query@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -5032,6 +5039,11 @@ follow-redirects@^1.0.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147"
integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==
+follow-redirects@^1.14.4:
+ version "1.14.5"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
+ integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
+
for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"