๋จผ์ ์ด์ ์ HTTP ์์ฒญ์ ์ ์กํ๋ ๊ฒ์ ๋ํ ๋ฐฉ๋ฒ์ ํ์ตํ ์ ์ด ์์ ๊ฒ์ด๋ค. ์ด๋ ์ฌ์ฉํ๋ Firebase์ realtime database์ URL ์ฃผ์๊ฐ ํ์ํ๋, ๊ทธ ์ฃผ์๋ฅผ ๊ธ์ด์ ํ์ฌ์ ์ดํ๋ฆฌ์ผ์ด์
์์ fetch๋ฅผ ํตํด ์ฌ์ฉํ๊ณ ์๋ URL ์ฃผ์๋ฅผ ๋์ฒดํ๋๋ก ํ์. ๋ฌผ๋ก Firebase ๊ฐ ์๊ตฌํ๋ ์กฐ๊ฑด /์ ์ฅํ๊ณ ์ ํ๋ ๋
ธ๋์ ์ด๋ฆ.json
์ URL ์ฃผ์ ๋ค์ ๋ถ์ด๋ ๊ฑธ ์์ง ๋ง์.
์ด ์ดํ๋ฆฌ์ผ์ด์ ์ ์ด๋ป๊ฒ ๋์๊ฐ๊น? ๋จผ์ URL์ Firebase์ realtime database์ URL ์ฃผ์๋ก ์์ ํด์ฃผ๊ณ ์ ์ฅํ ๋ค, ์๋ก๊ณ ์นจ์ ํด๋ณด์.
tasks
)๊ฐ ์์ฑ๋์์์ ํ์ธํ ์ ์๋ค.App
์ปดํฌ๋ํธ๋ก Task ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ fetchTask
ํจ์๊ฐ ์๋ ๋ถ๋ถ์ด๋ค.const fetchTasks = async (taskText) => {
setIsLoading(true);
setError(null);
try {
const response = await fetch(
"https://react-http-6b4a6.firebaseio.com/tasks.json"
);
if (!response.ok) {
throw new Error("Request failed!");
}
const data = await response.json();
const loadedTasks = [];
for (const taskKey in data) {
loadedTasks.push({ id: taskKey, text: data[taskKey].text });
}
setTasks(loadedTasks);
} catch (err) {
setError(err.message || "Something went wrong!");
}
setIsLoading(false);
};
fetchTasks
ํจ์๋ useEffect
๋ก ์ธํด ์คํ๋๊ฑฐ๋ App
์ปดํฌ๋ํธ๊ฐ ๋ฐํํ๋ Tasks
์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌ๋์ด ํด๋น ์ปดํฌ๋ํธ ๋ด๋ถ์์ ๋ฒํผ์ด ํด๋ฆญ๋๊ฑฐ๋ ํ๋ฉด์ ์คํ๋๊ณ ์๋ค. ์ด๋ ๊ฒ App
์ปดํฌ๋ํธ ์์์ fetchTasks
ํจ์๊ฐ ํธ๋ฆฌ๊ฑฐ ๋๊ณ ์๋ค.const enterTaskHandler = async (taskText) => {
setIsLoading(true);
setError(null);
try {
const response = await fetch(
"https://react-http-6b4a6.firebaseio.com/tasks.json",
{
method: "POST",
body: JSON.stringify({ text: taskText }),
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Request failed!");
}
const data = await response.json();
const generatedId = data.name; // firebase-specific => "name" contains generated id
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
} catch (err) {
setError(err.message || "Something went wrong!");
}
setIsLoading(false);
};
NewTask
์ปดํฌ๋ํธ๋ fetch API๋ฅผ ์ฌ์ฉํ๋ ๋ก์ง ํจ์ enterTaskHandler
๋ฅผ ๊ฐ์ง๊ณ ์๋ค. enterTaskHandler
ํจ์๋ App
์ fetchTasks
ํจ์์ฒ๋ผ HTTP ์์ฒญ์ ๋ณด๋ด๊ณ ์์ง๋ง, Firebase์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ "POST" ์์ฒญ์ด ์ ์ก๋๋ค. ์ด enterTaskHandler
ํจ์๋ TaskForm
์ปดํฌ๋ํธ๊ฐ ์ต์ข
์ ์ผ๋ก ์ ์ถ๋ ๋ ํธ๋ฆฌ๊ฑฐ ๋๋ ํจ์์ด๋ค. ์ฆ, TaskForm
์ปดํฌ๋ํธ๋ NewTask
์ปดํฌ๋ํธ๋ก๋ถํฐ props๋ก ํจ์๋ฅผ ๋ฐ์ ํด๋น ํจ์์์ ๋ฒํผ์ด ํด๋ฆญ๋๊ฑฐ๋ ์ธํ์ ์
๋ ฅ๋ ๊ฐ์ด ๊ฒ์ฆ๋๋ ์์ ์์ enterTaskHandler
๊ฐ ์คํ๋๋ ๊ฒ์ด๋ค.App
, NewTask
)๋ฅผ ์ดํด๋ณด๋ฉด์, fetch API๋ฅผ ์ฌ์ฉํด์ HTTP ์์ฒญ์ ํ๋ ๋ก์ง์ด ์ต์ ํ๋ ์ด์์ ์ปค์คํ
ํ
์ ์ถ๊ฐํ ์ ์๋ค๋ ๊ฑธ ์ ์ ์์๋ค. ์ด ๋๊ฐ์ HTTP ์์ฒญ์ ํ๋ ํจ์๊ฐ ๋ชจ๋ ๋์ผํ ๋ก์ง์ ๊ฐ์ง ๊ฒ์ ์๋์ง๋ง ํฌ๊ฒ ๋ ๊ฐ์ง์ ๋น์ทํ ์ข
๋ฅ์ ์์
์ ํ๊ณ ์์ ๊ฒ์ด๋ค. ์ ์ฅํ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๋ถ๋ถ๊ณผ, ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ์์ฒญ์ ๋ณด๋ด๋ ๋ถ๋ถ ๋ง์ด๋ค. ์ธ๋ฐํ๊ฒ ์ดํด๋ณด๋ฉด ์๋ต์ ๋ํ ๋ณํ ๋ก์ง์ ์กฐ๊ธ ๋ค๋ฅธ ํํ์ด์ง๋ง ์ค์ ๋ก ์ฝ๋๊ฐ ์ ์ฌํ ๋ถ๋ถ์ ์๋น์ ์กด์ฌํ๋ค. ๋ก๋ฉ๊ณผ ์ค๋ฅ ์ํ(state)๋ฅผ ๊ด๋ฆฌํ๊ณ ์ค์ ํ๋ ๊ฒ๊ณผ ์ค๋ฅ๋ฅผ ๋ค๋ฃจ๋ ๋ก์ง ์ญ์ ๋์ผํ๋ค. ์ด์ฒ๋ผ ๋น์ทํ ์ฝ๋๊ฐ ์กด์ฌํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด ๋ถ๋ถ์ ๋ก์ง์ ๋ณ๋์ ํจ์์ ์์์์ฑํ๋ ๊ฒ์ ๊ณ ๋ คํด๋ณผ ์ ์์ ๊ฒ์ด๋ค. ์ง๊ธ๊น์ง ๋ฐฐ์ด ์ปค์คํ
ํ
์ ํตํด์ ๋ง์ด๋ค.use-fetch.js
ํ์ผ์ ๋ง๋ ๋ค.const useFetch = () => {};
export default useFetch;
useFetch
์ปค์คํ
ํ
์ผ๋ก ์์์์ฑํ ๋ก์ง(App.js
)์ ํ์ธํ๋ค.const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const fetchTasks = async (taskText) => {
setIsLoading(true);
setError(null);
try {
const response = await fetch(
"https://react-http-6b4a6.firebaseio.com/tasks.json"
);
if (!response.ok) {
throw new Error("Request failed!");
}
const data = await response.json();
const loadedTasks = [];
for (const taskKey in data) {
loadedTasks.push({ id: taskKey, text: data[taskKey].text });
}
setTasks(loadedTasks);
} catch (err) {
setError(err.message || "Something went wrong!");
}
setIsLoading(false);
};
fetchTasks
ํจ์ ์ ์ฒด์ isLoading
, error
์ ์ํ(state) ์ฝ๋๊น์ง ๋ชจ๋ ๋ณต์ฌํด์ useFetch
์ปค์คํ
ํ
ํจ์ ์์ ๋ถ์ฌ ๋ฃ์ด์ค๋ค.const [tasks, setTasks] = useState([]);
tasks
์ํ(state)๋App
์ปดํฌ๋ํธ์๋ง ์ฌ์ฉํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ์ ์ธํ๊ณ ๋ชจ๋ ๋ณต์ฌํด์useFetch
์ปค์คํ ํ ์ ๋ฃ์ด์ฃผ์.
const useFetch = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const sendRequest = async (taskText) => {
setIsLoading(true);
setError(null);
try {
const response = await fetch(
"https://react-http-6b4a6.firebaseio.com/tasks.json"
);
if (!response.ok) {
throw new Error("Request failed!");
}
const data = await response.json();
const loadedTasks = [];
for (const taskKey in data) {
loadedTasks.push({ id: taskKey, text: data[taskKey].text });
}
setTasks(loadedTasks);
} catch (err) {
setError(err.message || "Something went wrong!");
}
setIsLoading(false);
};
return {
isLoading: isLoading,
error: error,
sendRequest: sendRequest,
};
};
App
์ปดํฌ๋ํธ์์ ๊ธ์ด์จ fetchTasks
ํจ์์ ์ด๋ฆ์ sendRequest
๋ก ์์ ํ๋ค. ์ด๋ ๊ฒ ์์ ํ๋ค๋ฉด ๋ด๋ถ์ ์๋ ๋ก์ง์ ์ข ๋ ์ผ๋ฐํ์ํฌ ์ ์๋ค. ์ด useFetch
์ปค์คํ
ํ
์ ๋ฐ์ดํฐ fetch ์๋ง ๊ตญํ๋์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ญํ ๋ง ํ๋ ๊ฒ์ด ์๋๋ผ, ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ์ญํ ๋ ํ๊ธฐ ๋๋ฌธ์ ์กฐ๊ธ ๋ ์ด๋ฆ์ ์ผ๋ฐํ ์ํค๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ์์ ํ๊ฒ ๋๋ฉด ํ
์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ ์ฌ๋ฌ ์์
์๋ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฑธ ๋ช
์์ ์ผ๋ก ์ ์ ์๊ฒ ๋๋ค.useFetch
์ปค์คํ
ํ
์ ์ด๋ค ์ข
๋ฅ์ ์์ฒญ์ด๋ ๋ฐ์์ ๋ชจ๋ ์ข
๋ฅ์ URL๋ก ๋ณด๋ผ ์ ์์ด์ผ ํ๊ณ , ๋ํ ์ด๋ค ๋ฐ์ดํฐ๋ ๋ณํ์ ํ ์ ์์ด์ผ ํ๋ค. ๋์์ ๋ก๋ฉ(isLoading
)๊ณผ ์ค๋ฅ(error
) ์ํ(state)๋ฅผ ๊ด๋ฆฌํ๊ณ , ๋ชจ๋ ๊ณผ์ ์ ๋์ผํ ์์๋๋ก ์คํํด์ผ๋ง ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ์ ์ฐํ ์ปค์คํ
ํ
์ ๋ง๋ค๊ธฐ ์ํด์๋ ๋ช ๊ฐ์ง์ ๋งค๊ฐ๋ณ์๊ฐ ํ์ํ๋ค.const response = await fetch(
"https://react-http-6b4a6.firebaseio.com/tasks.json"
);
const response = await fetch(
"https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
{
method: "POST",
body: JSON.stringify({ text: taskText }),
headers: {
"Content-Type": "application/json",
},
}
);
response
๋ก์ง ๋ถ๋ถ์ ๋ณด๋ฉด URL ์ ๋น๋กฏํ์ฌ, ๋ฉ์๋, body, headers ๋ฑ ์ ์ฐ์ฑ์ ๊ฐ์ถ์ด์ผ ํจ์ ์ ์ ์๋ค. NewTask
์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ HTTP ์์ฒญ์ "POST"์ด๊ธฐ ๋๋ฌธ์ fetch API๋ฅผ ์์ฒญํ ๋ URL ๋ฟ๋ง ์๋๋ผ, ๋ ๋ฒ์งธ ์ธ์์ ๋ฉ์๋, body, headers ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ํด๋น ์ค์ ์ ์ํ ๋งค๊ฐ๋ณ์(requestConfig
)๋ฅผ ์ถ๊ฐํ๋ค.const useFetch = (requestConfig) => {
...
}
requestConfig
๋ URL์ ํฌํจํด์ ์ด๋ค ์ข
๋ฅ์ ์ค์ ์ฌํญ๋ ํฌํจํ ์ ์๋ ๊ฐ์ฒด ํํ์ฌ์ผ๋ง ํ ๊ฒ์ด๋ค.const sendRequest = async (taskText) => {
setIsLoading(true);
setError(null);
try {
// โก๏ธ --------
const response = await fetch(requestConfig.url, {
method: requestConfig.method,
headers: requestConfig.headers,
body: JSON.stringify(requestConfig.body),
});
// โก๏ธ --------
if (!response.ok) {
throw new Error("Request failed!");
}
const data = await response.json();
applyData(data);
} catch (err) {
setError(err.message || "Something went wrong!");
}
setIsLoading(false);
};
requestConfig.url
๊ทธ๋ฆฌ๊ณ ์ค์ ๊ฐ์ฒด๋ ๊ฐ๊ฐ method
๋ requestConfig.method
, headers
๋ requestConfig.headers
, body
๋ JSON.stringify(requestConfig.body)
๋ก ํ ๋นํ๋ค. ์ด๋ ๊ฒ ํด์ผ, ์ธ๋ถ ์ปดํฌ๋ํธ์์ ์ปค์คํ
ํ
์ ํธ์ถํ ๋ URL ์ฃผ์๋ฅผ ๋ด์ ๊ฒ๊ณผ ํด๋น ์ค์ ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด(requestConfig
)๋ฅผ ์ ๋ฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ ๊ฒ ๋๋ฉด, "GET"์ผ๋ก URL๋ง ์์ฒญํ๋ ๋ก์ง ๋ฟ๋ง ์๋๋ผ, "POST"๋ก ์์ฒญํ ๋๋ ์ค์ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.const data = await response.json();
response
์ ๋ณํํ๊ธฐ๋ ํด์ผ ํ๋ค. JSON ๋ฐ์ดํฐ๋ง์ ๋ค๋ฃฐ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ์ด ๋ถ๋ถ์ ์์ ํ์ง ์๊ณ ๊ทธ๋๋ก ๋๋ค.const loadedTasks = [];
for (const taskKey in data) {
loadedTasks.push({ id: taskKey, text: data[taskKey].text });
}
setTasks(loadedTasks);
GET
์์ฒญ๋ง์ ์ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ)์ด๊ธฐ ๋๋ฌธ์ ์ปค์คํ
ํ
์ ํฌํจ๋์๋ ์๋ ๊ฒ์ด๋ค. ๋์ ์ ์ฌ๊ธฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉด, useFetch
์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ก๋ถํฐ ์ป์ ํจ์๋ฅผ ์คํํด์ ๊ทธ ํจ์์ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ ์ฌ์ฉํ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ธ๋ถ์ ์ธ ๋ณํ ๊ณผ์ ์ ์ปค์คํ
ํ
์ด ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ ์์์ ์ ์ํ ์ ์๊ฒ ๋๋ค. ๋ฐ๋ผ์ ์์ ์ฝ๋๋ฅผ ์ปค์คํ
ํ
๋ด๋ถ์์ ์คํํ์ง ์๊ณ , ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ํจ์๋ก ์ฒ๋ฆฌํด์ค ์ ์๋๋ก ํ๋ค.const useFetch = (requestConfig, applyData) => {
...
}
applyData
๋ผ๋ ์ด๋ฆ์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๊ธฐ๋ก ํ๋ค. ์์ฒญ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ ๋ค์ applyData
๋งค๊ฐ๋ณ์ ํจ์๋ฅผ ํธ์ถํด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค.const data = await response.json();
applyData(data);
useFetch
์ปค์คํ
ํ
์์ applyData
ํจ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๊ฒ์ด๋ฉฐ, applyData
ํจ์ ์์์ ๋ฌด์์ด ๋ฐ์ํ๋์ง์ ๋ํด์๋ applyData
์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์์ ์ ์ํ ์ ์๊ฒ ๋์๋ค. ์ด์ useFetch
์ปค์คํ
ํ
์์ ์ฌ์ฌ์ฉ๊ณผ ์ฌ์ฌ์ฉ ๋ก์ง์ ์ค๋นํ๋ค. ํ์ง๋ง ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ์ธ๋ถ์ ์ธ ๊ณผ์ ์ ํด๋น ์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์์๋ง ์ ์ํ ์ ์๋๋ก ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ๋ถ๋ฆฌ๋ฅผ ํด์ฃผ๋ ๊ฒ์ด ์ด์ ๋ณด๋ค๋ ์กฐ๊ธ ๋ ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์ธ๋ค. useFetch
์ปค์คํ
ํ
์๋ isLoading
๊ณผ error
๊ฐ์ ์ํ(state)์ HTTP ํต์ ์ ํ๋ sendRequest
ํจ์๊ฐ ํฌํจ๋์๋ค. ํ์ง๋ง ์ด๊ฒ๋ค์ ๊ฒฐ๊ตญ useFetch
์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์ ํ์ํ ๊ฒ๋ค์ด๋ค.useFetch
์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค์ ๋ก๋ฉ(isLoading
)๊ณผ ์ค๋ฅ(error
) ์ํ์ ๋ํด ์ ๊ทผํ ์ ์์ด์ผ ํ๊ณ , sendRequest
ํจ์์๋ ์ ๊ทผํ ์ ์์ด์ผ ํ๋ค. ๊ทธ๋์ผ์ง ํด๋น ์ปค์คํ
ํ
์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค์ด ์ด๊ฒ๋ค์ ํ์ฑํํ๊ณ ์์ฒญ ๋ํ ๋ณด๋ผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.const useFetch = (requestConfig, applyData) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const sendRequest = async (taskText) => {
...
};
return {}
};
useFetch
ํจ์ ๋ด๋ถ์ ๊ฐ์ฅ ํ๋จ์ผ๋ก ์ด๋ํ์ฌ ์ธ๋ถ ์ปดํฌ๋ํธ๋ค์ด ์ ๊ทผํ์ฌ ์ฌ์ฉํ ์ ์๋๋ก ์ํ(state)์ ํจ์๋ฅผ ๋ฐํํ๋ค. ์ด์ ์ ํ์ต์์ ์ธ๊ธํ๋ ๊ฒ์ฒ๋ผ ์ปค์คํ
ํ
์ ์ซ์๋ ๋ฌธ์์ด, ๋ฐฐ์ด, ๊ฐ์ฒด ๋ฑ๊ณผ ๊ฐ์ด ๋ฌด์์ด๋ ๋ฐํํ ์ ์๋ค. ์ด๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ ๊ฐ๋ค์ ๋ฐํํ ์์ ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด์ ํํ๋ก ๋ฐํํ ๊ฒ์ด๋ค.return {
isLoading: isLoading,
error: error,
sendRequest: sendRequest,
};
isLoading
, error
)์ ํจ์(sendRequest
)๋ฅผ ๋ฐํํ๋ค. ๊ฐ์ฒด์ ํค์ ๊ฐ์์ ์ผ์ชฝ์ ํค๋ ์์ฑ์ ์ด๋ฆ์ ๋งํ๊ณ , ์ค๋ฅธ์ชฝ์ ๊ฐ์ ๋ง ๊ทธ๋๋ก ๊ฐ์ ์๋ฏธํ๋ค.return {
isLoading,
error,
sendRequest,
};
App
์ปดํฌ๋ํธ๋ก ๋์์ ์ปค์คํ
ํ
(useFetch
)์ ์ฌ์ฉํด๋ณด์.import useFetch from "./hooks/use-fetch";
useFetch
ํ
์ import ํด์จ ๋ค ํธ์ถํด์ค์.useFetch();
useFetch
์์ ์ธ๋ถ ์ปดํฌ๋ํธ๋ก๋ถํฐ ๋ฐ๊ธฐ๋ก ํ ๊ทธ ๋งค๊ฐ๋ณ์๋ค ๋ง์ด๋ค.useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
๋ฐ์ดํฐ ์ฒ๋ฆฌ ํจ์
);
useFecth
๋ด๋ถ์์ fetch()
์์ ๋ฃ์ด์ค URL๊ณผ method, headers, body ๋ฑ์ ์์ฑ์ ํฌํจํ๊ณ ์๋ requestConfig
์ ๋ณด๋ผ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์ฃผ๋ ํจ์(applyData
)๋ฅผ ์ ๋ฌํด์ผ ํ๋ค. requestConfig
์ ๋ณด๋ด๋ ๊ฐ์ฒด๋ ๋ด๋ถ์ ํ์ํ ์์ฑ๋ค์ด ํฌํจ๋์ด ์์ด์ผ ํ๋ค. ์ปค์คํ
ํ
๋ด๋ถ์์ URL ๊ณผ method, headers, body ๋ฑ์ ์์ฑ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ App
์ปดํฌ๋ํธ์ url ์์ฑ์ ํด๋น ๋ฌธ์์ด ์ฃผ์๋ฅผ ํ ๋นํด์ค๋ค. ๊ทธ๋ ๋ค๋ฉด ๋๋จธ์ง method, headers, body ์์ฑ์ ์ ๋ฃ์ด์ฃผ์ง ์์๊น?App
์ปดํฌ๋ํธ ๋ด๋ถ์์ requestConfig
์ ๋ณด๋ด๋ ๊ฐ์ฒด์๋ ์ URL ๋ง ํฌํจ์์ผฐ์๊นuseFetch
์ปค์คํ
ํ
์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋๊ฐ์ ์ปดํฌ๋ํธ์ ์ฐจ์ด์ ์ ํ์ธํด๋ณด์. App
์ปดํฌ๋ํธ์์๋ ๋ฐ์ดํฐ๋ฅผ ๊ทธ์ ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ "GET" ์์ฒญ์ผ๋ก๋ง ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ณ , ์ฌ๊ธฐ์๋ method, headers, body ๋ฑ์ด ํ์ํ์ง ์๋ค. ๋ฐ๋ฉด, NewTask
์ปดํฌ๋ํธ๋ "POST" ์์ฒญ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ ๋ณด๋ด์ผ ํ๊ณ ์ฌ๊ธฐ์๋ method, headers, body ์ ์์ฑ์ด ํ์ํ๋ค. ์ด๋ ๊ฒ ํ์ํ ์์ฑ๋ค์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ์ ์ฐ์ฑ์ ์กฐ๊ธ ๋ ๊ฐ์ถฐ์ผํ ํ์๊ฐ ์๋ค. ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด์ ๋ค์ ์ปค์คํ
ํ
์ผ๋ก ๋์๊ฐ fetch()
์ Request ๋ถ๋ถ์ ์ ์ฐ์ฑ์ ๊ฐ์ถ ๋ก์ง์ผ๋ก ์์ ํด์ผ ํ๋ค.const response = await fetch(requestConfig.url, {
method: requestConfig.method,
headers: requestConfig.headers,
body: JSON.stringify(requestConfig.body),
});
useFetch
์ปค์คํ
ํ
์ผ๋ก ๋์์ response ๋ณ์์ fetch()
๋ก์ง์ ์์ ํ๋ค.const response = await fetch(requestConfig.url, {
method: requestConfig.method ? requestConfig.method : "GET",
headers: requestConfig.headers ? requestConfig.headers : {},
body: JSON.stringify(requestConfig.body)
? JSON.stringify(requestConfig.body)
: null,
});
method
์ ๊ฒฝ์ฐ์๋ requestConfig.method
๊ฐ ์ ์ฉ ๋์๋์ง๋ฅผ ํ์ธํ๊ณ (?
) ์ค์ ๋์์ ๋๋ง requestConfig.method
๋ฅผ ๋ถ์ฌํ๊ณ ์๋ ๋(:
)๋ "GET"์ผ๋ก ์์ฒญ์ ๋ณด๋ผ ์ ์๋๋ก ์์ ํ๋ค.headers
์ ๊ฒฝ์ฐ์๋ requestConfig.headers
๊ฐ ์ ์ฉ ๋์๋์ง๋ฅผ ํ์ธํ๊ณ (?
) ์ค์ ๋์์ ๋๋ง requestConfig.headers
๋ฅผ ๋ถ์ฌํ๊ณ ์๋ ๋(:
)๋ ๋น ๊ฐ์ฒด({}
)๋ฅผ ํ ๋นํ๋ค.body
์ ๊ฒฝ์ฐ์๋ JSON.stringify(requestConfig.body)
์ ์ค์ ์ํ๋ฅผ ํ์ธํ๊ณ (?
) ์ค์ ๋์์ ๋๋ง JSON.stringify(requestConfig.body)
๋ฅผ ๋ถ์ฌํ๊ณ ์๋ ๋(:
)๋ null
๋ก ํ ๋นํ๋ค. ์ด๋ ๊ฒ ์์ ํจ์ผ๋ก์จ ์ปค์คํ
ํ
์ ์ถฉ๋ถํ ์ ์ฐ์ฑ์ ๊ฐ์ถ๊ฒ ๋์๋ค.useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
๋ฐ์ดํฐ ์ฒ๋ฆฌ ํจ์
);
App
์ปดํฌ๋ํธ๋ก ๋์์ค์. ์ด์ App
์ปดํฌ๋ํธ์์ ํธ์ถํ useFetch
๊ฐ ์ด๋ฐ ํํ์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๊ฒ ๋์๋ค. ๊ฐ๋
์ฑ์ ์ํด ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง์ useFetch
์์ ์์ฑํ๋ค. ์ด์ ๋จ์ ๊ฑด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์์ธ ๋ ๋ฒ์งธ ์ธ์๋ฅผ ์ค๋นํ๋ ์ผ์ด๋ค.const transformTasks = (taskObj) => {};
useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
transformTasks
๋ผ๊ณ ํ๋ค. ์ฌ๊ธฐ์๋ taskObj
๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๋๋ค. ์ด transformTasks
ํจ์ ๋ด๋ถ์ useFetch
์์์ ์ฌ์ฉํ๋ ์ฆ, ์ด์ ์ ์ ๊ฑฐํ๋ ๊ทธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง์ ๊ทธ๋๋ก ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ๊ธฐ ํด์ค๋ค.const transformTasks = (taskObj) => {
const loadedTasks = [];
for (const taskKey in data) {
loadedTasks.push({ id: taskKey, text: data[taskKey].text });
}
setTasks(loadedTasks);
};
taskObj
์ธ์๋ฅผ data
๋ก ํ๊ธฐ๋ ์๋ฆฌ์ ๋์ ๋ฃ์ด์ฃผ๊ณ ,const transformTasks = (taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
};
for in
๋ฌธ์ ํตํด์ ์ฝ์ด์์ ๊ฐ์ฒด ํํ๋ก loadedTasks
์ด๋ผ๋ ๋น ๋ฐฐ์ด์ push ํด์ค๋ค. ์ด์ Firebase์์ ๋ฐ๋ ๊ฐ์ฒด์ ๋ชจ๋ ์์
์ ํ๋ก ํธ์๋์์ ํ์ํ ๊ตฌ์กฐ์ ์ ํ์ ๊ฐ๋ ๊ฐ์ฒด๋ก ๋ณํ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ setTasks
์ํ(state) ์
๋ฐ์ดํธ ํจ์์ ์ ๋ฌํ๋ค. ์ด๊ฒ์ผ๋ก useFetch()
์ ๋ ๋ฒ์งธ ์ธ์์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํจ์๊ฐ ์ค๋น๋์๋ค.useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
transformTasks
์ด ํจ์๋ ์ปค์คํ
ํ
์ด ์๋ต์ ๋ฐ๊ฒ ๋๋ฉด ์์์ ํธ์ถ๋ ๊ฒ์ด๋ค. ์ด๋ฐ ๋ฐฉ๋ฒ์ด ์ข์ ์ด์ ๋ ์ด๋ ๊ฒ ํ๋ฉด ์ฃผ์ ๋ก์ง์ ์ปค์คํ
ํ
์ ์์์์ฑ ํ ์ ์๊ฒ ๋๊ณ ๋ก์ง์ ๋ํ ๋ฐ์ดํฐ๋ ๊ทธ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ปดํฌ๋ํธ์ ์์นํ๊ฒ ๋๊ธฐ ๋๋ฌธ์ด๋ค.useFetch
์์ฒญ ํ์ฑํํ๊ธฐuseFetch
์ปค์คํ
ํ
์ ๋งค๊ฐ๋ณ์๋ง ๋ฐ๋ ๊ฒ์ด ์๋๋ผ ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐํํ๊ธฐ๋ ํ๋ค. isLoading
๊ณผ error
์ํ(state)๊ฐ ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉฐ, sendRequest
ํจ์์ ํฌ์ธํฐ ์ญ์ ๋ฐํํ๋ค. ๊ทธ๋ฆฌ๊ณ useFetch
์์ฒญ์ ํ์ฑํํ๊ธฐ ์ํด์๋ ํธ์ถ์ด ํ์ํ๋ค. ๋ฐ๋ผ์ App
์ปดํฌ๋ํธ์์ httpData
๋ ์ด๋ฆ์ผ๋ก useFetch
๋ฅผ ํธ์ถํ ์ ์๋๋ก ํ๊ณ ,const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
httpData
๋ฅผ ํฌ์ธํฐํด์ ๊ตฌ์กฐ๋ฅผ ๋ถํดํ๋ ๋ก์ง์ ์์ฑํ๋ค.const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
const {} = httpData;
isLoading
, error
, sendRequest
๋ฅผ ๊ฐ์ฒด ๊ตฌ์กฐ ๋ถํด ํ ๋น์ ํตํด ์ถ์ถํ๋ค.const { isLoading, error, sendRequest } = httpData;
App
์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ๋ณ์นญ์ ์์ฑํ ๊ฒ์ธ๋ฐ, ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ด ๋ถํด ๋ฌธ๋ฒ์ ์ฝ๋ก (:
)์ ์ถ๊ฐํ๋ฉด ๋ค๋ฅธ ์ด๋ฆ์ ๋ถ์ฌํ ์ ์๊ธฐ์ ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ ์๋ก์ด ์ด๋ฆ์ ๋ถ์ฌํ๋ค.const { isLoading, error, sendRequest: fetchTasks } = httpData;
sendRequest
์ ์๋ก์ด ์ด๋ฆ์ผ๋ก fetchTasks
๋ฅผ ์ค์ ํ๋ค. ์ด๋ ์ปค์คํ
ํ
๋ด๋ถ์ sendRequest
ํจ์๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ํฌ์ธํฐ์ ์ด๋ฆ์ธ ๊ฒ์ด๋ค. ๋จ์ํ ์ด๊ฒ์ ์ฌ์ฉํ App
์ปดํฌ๋ํธ ํจ์ ์์์ sendRequest
ํจ์๋ฅผ ๊ฐ๋ฆฌํค๋ ์ด๋ฆ๋ง ๋ฐ๊พผ ๊ฒ์ด๋ค.useEffect(() => {
fetchTasks();
}, []);
fetchTasks()
๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋๊ณ , ์๋์ useEffect
ํ
๋ก์ง์ ์์ ํ ํ์๋ ์์ ๊ฒ์ด๋ค.useEffect
์ ์์กด์ฑ์ ์ถ๊ฐ ๋ฌธ์ useEffect
ํ
์ ์์กด์ฑ ๋ฐฐ์ด์ ๋ฌด์ธ๊ฐ ์ค๋ฅ๊ฐ ์์์ ๊ฒฝ๊ณ ํ๋ ๊ฑธ ์ ์ ์๋ค. ์ด์ ์ ์ฌ์ฉํ๋ fetchTasks
ํจ์์์๋ ๋ฌธ์ ๊ฐ ๋์ง ์๋ ๊ฒ์ด๋ค. ์ด์ ์๋ ์ํ ๊ฐฑ์ ํจ์๋ง ํธ์ถํ๊ณ ์์๊ธฐ ๋๋ฌธ์ ์์กด์ฑ ๋ฐฐ์ด์ ๊ตณ์ด ์ฃผ์
ํ์ง ์์๋ ์๊ด ์์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง fetchTasks
ํจ์, ์ฆ ๋ด๋ถ์ sendRequest
ํจ์๋ ์ปค์คํ
ํ
๋ด๋ถ์ ์์นํด์๊ณ , ์ด๋ฅผ ์ถ์ถํด์ ์ฌ์ฉํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ useEffect
๋ ์ด sendRequest
ํจ์ ์์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง๋ฅผ ์์ง ๋ชปํ๋ค. ๋๋ฌธ์ fetchTasks
ํจ์๊ฐ ๋ณํํ ๋๋ง๋ค useEffect
๋ฅผ ์ฌ์คํํ๋ ค๋ฉด fetchTasks
๋ฅผ ์์กด์ฑ์ผ๋ก ์ถ๊ฐํด์ผ ํ๋ค.useEffect(() => {
fetchTasks();
}, [fetchTasks]);
useEffect(() => {
fetchTasks();
}, []);
App
์ปดํฌ๋ํธ๋ฅผ ์ฌ๊ตฌ์ถํ๋ค. ์ด์ isLoading
๊ณผ error
์ํ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ณ , ์ด๊ฒ๋ค์ Tasks
์ปดํฌ๋ํธ ๋ด๋ถ์ ์๋ ์์ ์ปดํฌ๋ํธ์ธ Task
์ปดํฌ๋ํธ์ ์ ๋ฌ๋๋ค. fetchTasks
ํจ์์๋ ์ ๊ทผ ๊ฐ๋ฅํ์ง๋ง ์์ฒญ์ ๋ณด๋ด๊ฑฐ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ถ๋ถ์ ์ปค์คํ
ํ
์ ์ผ๋ถ๊ฐ ๋์๋ค.๐จ ํด๋น ํฌ์คํ ์ Udemy์ โReact ์๋ฒฝ ๊ฐ์ด๋โ ๊ฐ์๋ฅผ ๋ฒ ์ด์ค๋ก ํ ๊ธฐ๋ก์ ๋๋ค.
โ๐ป ๊ฐ์ git repo ๋ฐ๋ก๊ฐ๊ธฐ