App
μ»΄ν¬λνΈμ useEffect
μ fetchTasks
λ₯Ό μμ‘΄μ±μΌλ‘ μΆκ°ν΄μΌ νλ€. μλνλ©΄ μ»΄ν¬λνΈ ν¨μ μμμ μ€μ λ λͺ¨λ λ°μ΄ν°, λλ ν¨μλ κ·Έ ν¨μμ μμ‘΄μ±μΌλ‘μ μΆκ°λμ΄μΌ νκΈ° λλ¬Έμ΄λ€.useEffect(() => {
fetchTasks();
}, [fetchTasks]);
useEffect
λ΄λΆμμ fetchTasks()
ν¨μλ₯Ό νΈμΆνλλ°, κ·Έλ κ² λλ©΄ 컀μ€ν
ν
μμ μλ sendRequest
ν¨μλ₯Ό μ€ννκ² λκ³ , λͺ λͺ μν(state)κ° μλ‘ μ€μ λκΈ° λλ¬Έμ΄λ€.App
μ»΄ν¬λνΈ λ΄λΆμμ ν
μ μ¬μ©νκ² λλ©΄, μ»΄ν¬λνΈλ 묡μμ μΌλ‘ 컀μ€ν
ν
μ΄ μ€μ ν μν(state)λ₯Ό μ¬μ©νκ² λλ€. μ¦, 컀μ€ν
ν
μμ ꡬμ±λ μν(state)κ° κ·Έ 컀μ€ν
ν
μ μ¬μ©νλ μ»΄ν¬λνΈμ μ€μ λκ² λλ κ²μ΄λΌλ λ»μ΄λ€.const sendRequest = async (taskText) => {
setIsLoading(true);
setError(null);
try {
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,
});
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);
};
sendRequest
ν¨μμμ setIsLoading
κ³Ό setErrer
λ₯Ό νΈμΆνλ©΄ μ΄λ App
μ»΄ν¬λνΈμ μ¬λ λλ§μ λ°μμν¨λ€. μ κ·Έλ΄κΉ? μ΄λ App
μ»΄ν¬λνΈ μμ μλ 컀μ€ν
ν
μ μ¬μ©νλ κ²μ΄κΈ° λλ¬Έμ΄λ€. κ·Έλ κ² λλ©΄, μ¬λ λλ§μ΄ λλ μκ° μ»€μ€ν
ν
(useFetch
)μ΄ λ€μ νΈμΆλκ³ , 컀μ€ν
ν
(useFetch
)μ΄ λ€μ νΈμΆλλ©΄ sendRequest
ν¨μκ° λ λ€μ μ¬μμ±λλ©΄μ μλ‘μ΄ ν¨μ κ°μ²΄λ₯Ό λ°ννκ³ App
μ»΄ν¬λνΈμ useEffect
κ° μ¬μ€νλλ€.useEffect(() => {
fetchTasks();
}, [fetchTasks]);
useEffect
κ° μ΄λ₯Ό μλ‘μ΄ κ°μΌλ‘ λ°μλ€μ΄κ² λλ©° κΈ°μ μ μΌλ‘ κ°μ ν¨μμΌμ§λΌλ μ¬μ€νμ μ λ°νκ² λλ€.useFetch
컀μ€ν
ν
μΌλ‘ λμκ°μ sendRequest
λΆλΆμ μμ ν΄μΌ νλ€.const sendRequest = useCallback(async (taskText) => {
setIsLoading(true);
setError(null);
try {
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,
});
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);
}, []);
async/await
κ΅¬λ¬Έμ΄ μλλΌλ λ¬Έμ κ° μκΈ° λλ¬Έμ ν΄λΉ ν¨μ λΆλΆμ useCallback
μΌλ‘ κ°μΈμ. μλ€μνΌ useCallback
μ μμ‘΄μ± λ°°μ΄μ΄ νμνλ€. μ¬κΈ°μ 무μμ μ£Όμ
ν΄μΌ ν κΉ?const useFetch = (requestConfig, applyData) => {
...
const sendRequest = useCallback(
async (taskText) => {
setIsLoading(true);
setError(null);
try {
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,
});
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, applyData]
// β‘οΈ --------
);
...
};
useFetch
컀μ€ν
ν
μ΄ λ§€κ°λ³μλ‘ λ°μμ€λ requestConfig
μ applyData
λ₯Ό μΆκ°ν μ μμ κ²μ΄λ€. νμ§λ§ μ΄λ κ² νμ κ²½μ° λ λ€λ₯Έ λ¬Έμ κ° λ°μνλ€. λΉμ°ν μ΄μΌκΈ°κ² μ§λ§ μ΄ λκ°μ§ λͺ¨λ κ°μ²΄μ΄λ€. requestConfig
λ μλ°μ€ν¬λ¦½νΈ κΈ°λ³Έ κ°μ²΄μ΄κ³ , applyData
λ ν¨μμΈλ° μλ°μ€ν¬λ¦½νΈμμλ ν¨μ μμ κ°μ²΄μ΄κΈ° λλ¬Έμ΄λ€. λ€μ App
μ»΄ν¬λνΈλ‘ λμκ°μ useFetch
μ μ λ¬ν κ°μ²΄λ€μ μ΄ν΄λ³΄μ.const transformTasks = (taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
};
const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
const { isLoading, error, sendRequest: fetchTasks } = httpData;
useFetch
μ μΈμλ‘ μ λ¬νλ λ κ°μ κ°μ²΄κ° App
μ»΄ν¬λνΈκ° μ¬μ€νλ λλ§λ€ μ¬μμ±λμ§ μλλ‘ ν΄μΌ νλ€. νμ¬λ‘μλ App
μ»΄ν¬λνΈκ° μ¬μ€νλ λλ§λ€ μ¬μ€νλκ³ μκΈ° λλ¬Έμ΄λ€.const transformTasks = useCallback((taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
}, []);
transformTasks
ν¨μλ₯Ό useCallback
μΌλ‘ λννλ€. μ¬κΈ°μμμ μμ‘΄μ± λ°°μ΄μλ μ무 κ²λ μΆκ°νμ§ μλλ€. μν(state) μ
λ°μ΄νΈλ₯Ό νλ setTasks
μΈμλ κ·Έ μ΄λ ν κ²λ μΈλΆμμ μ°κ³ μμ§ μκΈ° λλ¬Έμ΄λ€. μ΄μ μ°λ¦¬λ transformTasks
ν¨μκ° λ³νμ§ μμμ useCallback
μ ν΅ν΄ 보μ¦νλ€.const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
httpData
) λ΄λΆμμ 첫 λ²μ§Έ μΈμλ‘ url μ λ΄μ μ λ¬νλ κ°μ²΄λ App
μ»΄ν¬λνΈκ° μ¬νκ°ν λλ§λ€ μ¬μμ±λκ³ μλ€. μ΄λ₯Ό λ§μΌλ €λ©΄, useMemo
μ κ°μ κ²μ μ΄μ©ν΄μ κ°μ²΄κ° λ³νμ§ μλλ‘ λ³΄μ¦ν΄μΌ ν κ²μ΄λ€. λλ useMemo
λ₯Ό μ¬μ©νλ λμ 컀μ€ν
ν
μ μ‘°κΈ μμ νλ λ°©λ²μ μ¬μ©ν΄λ λ κ²μ΄λ€.const useFetch = (requestConfig, applyData) => {
...
const sendRequest = useCallback(
async (taskText) => {
setIsLoading(true);
setError(null);
try {
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,
});
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, applyData]
// β‘οΈ --------
);
...
};
useFetch
컀μ€ν
ν
μμ 맀κ°λ³μλ‘ λ°λ requestConfig
λ ν
μ체μμ λ°μ§ μκ³ ν΄λΉ requestConfig
λ₯Ό μ¬μ©νλ sendRequest
ν¨μμ μΈμλ‘ μ§μ λ°μμ¨λ€λ©΄ μ΄λ¨κΉ? κ²°κ΅ sendRequest
ν¨μ μμ ν¨κ» νΈμΆλκΈ° λλ¬Έμ΄λ€.const useFetch = (applyData) => {
...
const sendRequest = useCallback(
// β‘οΈ --------
async (requestConfig) => {
// β‘οΈ --------
setIsLoading(true);
setError(null);
try {
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,
});
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);
},
// β‘οΈ --------
[applyData]
// β‘οΈ --------
);
...
};
requestConfig
λ₯Ό 컀μ€ν
ν
μμ²΄κ° μλ sendRequest
μμ μ§μ λ°μμ¬ μ μλλ‘ μμ νλ€. μ΄λ κ² λλ©΄ requestConfig
λ₯Ό μμ‘΄μ± λ°°μ΄μ μΆκ°νμ§ μμλ λ κ²μ΄λ€. μ΄μ requestConfig
λ μΈλΆμ μμ‘΄μ± λ°°μ΄μ΄ μλλΌ, useCallback
μΌλ‘ λνλ ν¨μμ 맀κ°λ³μκ° λμκΈ° λλ¬Έμ΄λ€.const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
App
μ»΄ν¬λνΈλ‘ μ΄λν΄μ μ΄ url κ°μ²΄λ₯Ό μ κ±°νλλ‘ νμ.const httpData = useFetch(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
transformTasks
κ° useFetch
μ μ λ¬λλ μ μΌν 맀κ°λ³μκ° λλ€.const httpData = useFetch(transformTasks);
const { isLoading, error, sendRequest: fetchTasks } = httpData;
const { isLoading, error, sendRequest: fetchTasks } = useFetch(transformTasks);
useEffect(() => {
fetchTasks();
}, [fetchTasks]);
useEffect
μμλ fetchTasks()
λ₯Ό ν΅ν΄μ μ΅μ’
μ μΌλ‘ μμ²μ μ λ¬νκ³ μλ€. fetchTasks()
κ° κ²°κ΅μλ μ°λ¦¬κ° μ΄μ μ useFetch
컀μ€ν
ν
λ΄λΆμμ μ€μ νλ sendRequest
ν¨μλΌλ κ±Έ κΈ°μ΅ν΄λ³΄μ. μ¬κΈ°μ μ°λ¦¬κ° μ λ¬νκΈ°λ‘ ν 맀κ°λ³μ requestConfig
λ₯Ό fetchTasks()
μ μ§μ μ λ¬ ν΄μ£Όμ΄μΌ ν κ²μ΄λ€.useEffect(() => {
fetchTasks({
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
});
}, [fetchTasks]);
transformTasks
)μλ μ΄μ λμΌν μμ
μ ν΄μ€ μ μλ€.const transformTasks = useCallback((taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
}, []);
const { isLoading, error, sendRequest: fetchTasks } = useFetch(transformTasks);
useEffect(() => {
fetchTasks({
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
});
}, [fetchTasks]);
App
μ»΄ν¬λνΈμμ useCallback
μ μ¬μ©νλ κ²μ΄ λ무 λ²κ±°λ‘λ€κ³ μκΉν κ²½μ° useCallback
μ μ κ±°νκ³ transformTasks
ν¨μλ₯Ό μ§μ fetchTasks()
μ μ λ¬νλ λ°©λ²λ μμ κ²μ΄λ€.// β‘οΈ --------
const transformTasks = (taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
};
// β‘οΈ --------
const { isLoading, error, sendRequest: fetchTasks } = useFetch();
useEffect(() => {
fetchTasks(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
// β‘οΈ --------
transformTasks
);
}, [fetchTasks]);
transformTasks
λ₯Ό useEffect
λ₯Ό λ΄λΆμμ μ€νν μ μλλ‘ μμ ν΄μ€λ€.const { isLoading, error, sendRequest: fetchTasks } = useFetch();
useEffect(() => {
const transformTasks = (taskObj) => {
const loadedTasks = [];
for (const taskKey in taskObj) {
loadedTasks.push({ id: taskKey, text: taskObj[taskKey].text });
}
setTasks(loadedTasks);
};
fetchTasks(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
}, [fetchTasks]);
transformTasks
ν¨μλ₯Ό useEffect
λ΄λΆμμ μ€ννκ² λλ©΄, Effect
ν¨μ μμ λ¨μμλ μΈλΆ μμ‘΄μ±μ μ¬λΌμ§κ² λλ€. μ΄μ useFetch
컀μ€ν
ν
μ μμ‘΄μ±μ΄λ μ΄λ ν 맀κ°λ³μ μμ΄λ νΈμΆμ΄ κ°λ₯ν΄μ§ κ²μ΄λ€.fetchTasks(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
},
transformTasks
);
requestConfig
)κ³Ό λ°μ΄ν° μ μ‘ ν λ°μ΄ν° μ²λ¦¬λ₯Ό ν΄μ£Όλ λ‘μ§(transformTasks
)μ μ§μ 보λ΄κΈ° λλ¬Έμ΄λ€.μ§κΈκΉμ§ λ κ°μ§ λ°©λ²μ μ¬μ©ν΄μ
useEffect
μ 무ν 루νμ λν μ루μ μ μ μ©ν΄λ΄€λ€. λ λ°©λ² λͺ¨λ μ¬μ© κ°λ₯ν λ°©λ²μ΄λ μ·¨ν₯λλ‘ μ νν΄μ μ¬μ©νλ©΄ λ κ²μ΄λ€.
transformTasks
λ°μ΄ν° μ²λ¦¬ ν¨μλ useFetch
컀μ€ν
ν
μμ μ§μ λ°μ§ μκ³ sendRequest
ν¨μμμ 맀κ°λ³μλ‘ λ°μ μ μλλ‘ μμ ν΄μ€λ€.const useFetch = () => {
...
const sendRequest = useCallback(
async (requestConfig, applyData) => {
setIsLoading(true);
setError(null);
try {
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,
});
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);
},
[applyData]
);
...
};
useCallback
μ μμ‘΄μ±μΌλ‘ μΆκ°νλ applyData
λ₯Ό μμ ν΄μ€λ€. useFetch
컀μ€ν
ν
μμλ λμ΄μ μμ‘΄μ±μ΄ νμνμ§ μμΌλ©°, μ΄λ ν΄λΉ 컀μ€ν
ν
μ΄ λ€λ£¨λ λͺ¨λ λ°μ΄ν°λ useCallback
μΌλ‘ λνλ ν¨μμμ 맀κ°λ³μλ‘ μ§μ λ°μμ€κ³ μκΈ° λλ¬Έμ΄λ€.const useFetch = () => {
...
const sendRequest = useCallback(
async (requestConfig, applyData) => {
setIsLoading(true);
setError(null);
try {
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,
});
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);
},
// β‘οΈ --------
[]
// β‘οΈ --------
);
...
};
μ μ₯νκ³ , μλ‘κ³ μΉ¨ ν΄λ³΄λ©΄ λμΌνκ² μμ μ΄ λ¬Έμ μμ΄ λμκ°κ³ μλ€λ κ±Έ μ μ μλ€.
NeweTasks
μ»΄ν¬λνΈμ 컀μ€ν
ν
μ μ μ©ν΄λ³΄λ €κ³ νλ€. λ¨Όμ NewTasks
μ»΄ν¬λνΈμ useFetch
λ₯Ό import ν΄μ¨ ν,import useFetch from "../../hooks/use-fetch";
useFetch
λ₯Ό νΈμΆνλ€.useFetch();
App
μ»΄ν¬λνΈμμ μμ±νλ κ²μ²λΌ NewTasks
μ»΄ν¬λνΈμμ μ¬μ©νκ³ μ νλ 컀μ€ν
ν
(useFetch
)μ μν(state)μ ν¨μλ₯Ό ꡬ쑰 λΆν΄ ν λΉμΌλ‘ μΆμΆνλ€.const { isLoading, error, sendRequest: sendTaskRequest } = useFetch();
enterTaskHandler
ν¨μκ° νΈλ¦¬κ±° λ λλ§λ€ ν΄λΉ 컀μ€ν
ν
μ νΈμΆνλλ‘ μμ±ν΄μ€λ€. μ¦, λ§€λ² TaskForm
μ»΄ν¬λνΈμμ νΌμ΄ μ μΆλ λλ§λ€ enterTaskHandler
ν¨μκ° νΈλ¦¬κ±° λκ³ , λ΄λΆμ ν¨μsendTaskRequest
ν¨μκ° νΈμΆλ μ μλλ‘ νλ κ²μ΄λ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest();
...
};
App
μ»΄ν¬λνΈμμ 컀μ€ν
ν
μ μ λ¬νμλ κ²κ³Ό λμΌνκ² sendTaskRequest
ν¨μ λ΄λΆμ μ ν©ν 맀κ°λ³μλ€μ μ λ¬ν΄μ€μΌ νλ€. 첫 λ²μ§Έ μΈμλ‘λ, response λ₯Ό ν λ νμνλ μμ±λ€μ΄ λ΄κΈ΄ κ°μ²΄κ° νμν κ²μ΄λ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest({
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
});
...
};
App
μ»΄ν¬λνΈμλ λ€λ₯΄κ² "POST" μμ²μ λ³΄λΌ κ²μ΄κΈ° λλ¬Έμ, "POST" μμ²μ λ³΄λΌ λ νμν μμ±(method
, headers
, body
) λν ν¬ν¨ν΄μ μμ±ν΄μ£Όμ΄μΌ νλ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest({
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
...
};
body
μμ±μ κ°μ JSON.stringify({text: taskText})
λ‘ λ³ννμ¬ λ³΄λμ§λ§, μ΄λ―Έ 컀μ€ν
ν
λ΄λΆμμ JSON λ³νμ ν΄μ£Όκ³ μμΌλ―λ‘ κ°μ²΄ ννλ‘ μμ±ν΄μ 보λ΄μ€λ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest({
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: { text: taskText },
});
...
};
useFetch
컀μ€ν
ν
μμ λ°μ 첫 λ²μ§Έ μΈμμΈ requestConfig
κ°μ²΄κ° μμ±λμλ€. λ λ²μ§Έλ‘ μ λ¬ν μΈμλ μλ΅ λ°μ΄ν°λ₯Ό λ°μμ μ²λ¦¬ν΄μ£Όλ ν¨μ applyData
μ΄λ€. NewTasks
μ»΄ν¬λνΈμμ λ°μ΄ν°λ₯Ό μ²λ¦¬νλ λ°©μμ μ΄ν΄λ³΄λ©΄,const data = await response.json();
// β‘οΈ --------
const generatedId = data.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
// β‘οΈ --------
generatedId
λ Firebase κ° μλμΌλ‘ λ§λ€μ΄μ£Όλ name
μΌλ‘ id
λ₯Ό μμ±ν΄μ€ κ²μ΄κ³ , μ΄ id
λ₯Ό λΉλ‘―νμ¬ νΌμΌλ‘ λΆν° μ λ¬λ°μ taskText
μ ν¨κ» ν¬ν¨νκ³ μλ κ²μ΄ createdTask
κ°μ²΄μ΄λ€. κ·Έλ¦¬κ³ μ΄κ²λ€μ props.onAddTask(createdTask)
λ‘ νΈμΆν΄μ λ£μ΄μ£Όμ΄μΌ νλ€.const createTask = (taskData) => {
const generatedId = data.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
};
createTask
ν¨μλ μμ λ‘μ§λ€μ λ΄μ μλ‘μ΄ ν¨μμ΄λ€. μ΄ ν¨μμμλ taskData
λ₯Ό μΈμλ‘ λ°λλ‘ μμ±ν΄μ€λ€. κ·Έλ¦¬κ³ κ·Έ μΈμμ λ°λΌ λ‘μ§λ€μ μμ ν΄μ€λ€.const createTask = (taskData) => {
const generatedId = taskData.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
};
sendTaskRequest
μ λ λ²μ§Έ μΈμλ‘ ν΄λΉ ν¨μ(createTask
)λ₯Ό ν¬μΈν°νλ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask
);
};
useCallback
μ μ¬μ©ν΄μΌ ν μ§ κ³ λ―Όλκ² μ§λ§ μ¬κΈ°μμλ ν΄λΉ ν
μ μ¬μ©νμ§ μμλ λλ€. App
μ»΄ν¬λνΈμ²λΌ useEffect
λ₯Ό μ¬μ©ν΄μ sendRequest
λ₯Ό νΈμΆνλ κ²μ΄ μλλΌ, enterTaskHandler
μμλ§ sendTaskRequest
λ₯Ό νΈμΆνκ³ μκΈ° λλ¬Έμ΄λ€. κ·Έλ¦¬κ³ μ΄ μμ²μ μ»΄ν¬λνΈκ° μ¬νκ°λμ΄λ μ μ‘λμ§ μμΌλ©°, λ¨μ§ 물리μ μΌλ‘ μ°λ¦¬κ° νΌμ μ μΆνμ λμλ§ ν¨μκ° μ¬μ€νλ κ²μ΄λ€. μ΄λ App
μ»΄ν¬λνΈμ λΆλͺ
λ€λ₯Έ μ μ΄λ€.createTask
ν¨μλ₯Ό 보면,const createTask = (taskData) => {
const generatedId = taskData.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
};
text
μμ± κ°μΌλ‘ μ λ¬ν΄μΌ νλ taskText
λΆλΆμ΄ μ λλ‘ μ λ¬λμ§ μμμμ μ μ μλ€. νΌμμ HTTP μμ²μ ν΅ν΄ μ λ¬λ ν
μ€νΈ λΆλΆμ΄ λΉ μ Έμλ κ²μ΄λ€. μ΄ taskText
λ enterTaskHandler
ν¨μμ 맀κ°λ³μλ₯Ό ν΅ν΄ λ°μμ€κ³ μλ€. κ·Έλ λ€λ©΄ μ΄λ»κ² μ΄λ₯Ό μ λ¬ν΄μΌ νλ κ±ΈκΉ? μ΄ taskText
λ₯Ό μ¬μ©νκΈ° μν΄μλ λ κ°μ μ νμ§κ° μλ€. 첫 λ²μ§Έλ‘λconst enterTaskHandler = async (taskText) => {
const createTask = (taskData) => {
const generatedId = taskData.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
};
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask.bind(null, taskText)
);
};
createTask
ν¨μλ₯Ό ν΅μ§Έλ‘ κ°μ Έμμ enterTaskHandler
ν¨μ μμμ μ μνλ λ°©λ²μ΄ μλ€. μ΄λ μλ°μ€ν¬λ¦½νΈ μ€μ½νμ λ°λΌ ν¨κ» μλλκ³ , taskText
λ₯Ό μ§μ λ°κΈ° λλ¬Έμ λλ λ¬Έμ κ° λμ§ μμ κ²μ΄λ€. μ΄μ²λΌ 볡μ‘ν μ€μ²© ꡬ쑰λ₯Ό νΌνκΈ° μν΄μ λ€λ₯Έ λ°©λ²μ μ¬μ©ν΄λ λλ€.const createTask = (taskData, taskText) => {
const generatedId = taskData.name;
const createdTask = { id: generatedId, text: taskText };
props.onAddTask(createdTask);
};
taskText
λ₯Ό createTask
ν¨μμ λ λ²μ§Έ μΈμλ‘ μΆκ°ν΄μ£Όλ κ²μ΄λ€. λ°λΌμ 컀μ€ν
ν
μλ 2κ°μ 맀κ°λ³μκ° νμνκ² λλ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask
);
};
createTask
ν¨μλ₯Ό νΈμΆνλ 컀μ€ν
ν
μ νλμ 맀κ°λ³μλ§μ μ λ¬νλ€.applyData(data);
bind()
λ₯Ό μ¬μ©νλ©΄ λλ€.bind()
λ©μλ μ¬μ©νκΈ°sendTaskRequest
μ μ λ¬νλ €λ createTask
μ bind()
λ©μλλ₯Ό νΈμΆνλ€. κ·Έλ¬λ©΄ bind()
λ©μλλ ν¨μλ₯Ό μ¬μ μ ꡬμ±ν μ μλλ‘ ν΄μ€λ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask.bind()
);
};
sendTaskRequest
μ μ λ¬νλ €λ creatTask
μ bind()
λ₯Ό νΈμΆν΄μ€λ€. κ·Έλ¬λ©΄ bind
λ©μλλ ν¨μλ₯Ό μ¬μ μ ꡬμ±ν΄μ€ κ²μ΄λ€.νΈμΆ μ¦μ ν¨μκ° μ€νλμ§λ μλλ€. μ΄κ²μ μλ°μ€ν¬λ¦½νΈμ κΈ°λ³Έμ μΈ λ©μλμ΄λ―λ‘ μ΄λ€ ν¨μμ λν΄μλ μ¬μ μ ꡬμ±νκΈ° μν΄μλ
bind()
λ₯Ό μ¬μ©ν μ μλ€.
const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask.bind(null)
);
};
bind()
λ©μλμ 보λ΄λ 첫 λ²μ§Έ μΈμλ μ€νμ΄ μμ λ ν¨μμμ this
μμ½μ΄λ₯Ό μ¬μ©νκ² λ§λλ κ²μ΄μ§λ§ μ¬κΈ°μλ νμκ° μκΈ° λλ¬Έμ null
λ‘ μ€μ νλ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask.bind(null, taskText)
);
};
bind()
λ©μλμ 보λ΄λ λ λ²μ§Έ μΈμλ νΈμΆ μμ μΈ ν¨μ(createTask
)κ° μ λ¬λ°λ 첫 λ²μ§Έ μΈμμ¬μΌλ§ νλ€.const createTask = (taskData, taskText) => {
...
};
taskText
λ₯Ό μ λ¬νλ €λ©΄ bind()
λ©μλμ λ λ²μ§Έ μΈμμ taskText
λ₯Ό μ λ¬ν΄μ μ μΆλ νΌ(enterTaskHandler
)μμ taskText
λ₯Ό μ°Ύλλ‘ λ§λ€λ©΄ λλ€.const enterTaskHandler = async (taskText) => {
sendTaskRequest(
{
url: "https://react-http-9914f-default-rtdb.firebaseio.com/tasks.json",
method: "POST",
body: { text: taskText },
headers: {
"Content-Type": "application/json",
},
},
createTask.bind(null, taskText)
);
};
useFetch
μμ μ λ¬λλ λ€λ₯Έ μΈμμ κ²½μ° κ°λ¨νκ² μ΄ λ§€κ°λ³μμ λͺ©λ‘ λμ μΆκ°νμ¬ μ²λ¦¬νλ©΄ λλ€.const sendRequest = useCallback(async (requestConfig, applyData) => {
...
const data = await response.json();
applyData(data);
...
}, []);
applyData
μ μ μΌν μΈμλ‘ μ λ¬λλ λ°μ΄ν°λ createTask
μ λ λ²μ§Έ μΈμλ‘ μΆκ°λλ€. μ΄μ νΈμΆμ΄ λλ©΄, μ΄λ μ°λ¦¬κ° μνλ λͺ¨λ λ°μ΄ν°λ₯Ό λ°κ² λλ€.π¨ ν΄λΉ ν¬μ€ν μ Udemyμ βReact μλ²½ κ°μ΄λβ κ°μλ₯Ό λ² μ΄μ€λ‘ ν κΈ°λ‘μ λλ€.
βπ» κ°μ git repo λ°λ‘κ°κΈ°