๐คทโ๏ธ ๋ฆฌ์กํธ์ ํ์ ์คํฌ๋ฆฝํธ ์กฐํฉ
React์ Typescript๋ ๊ฐ๋ ฅํ ์กฐํฉ์ผ๋ก ์ฝ๋ ๋ฒ ์ด์ค๋ฅผ ๋์ฑ ์์ ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ ๋ฌธ์ ๋ถ๋ค๊ป์๋ React hook์ Typescript๋ฅผ ์ ์ํ๋ ๊ฒ ๋ถํธํ๊ณ ๊น๋ค๋ก์ธ ์๋ ์์ต๋๋ค.
์ด ๊ธ์ ํตํด์ useState, useEffect, useContext, useRef ๊ทธ๋ฆฌ๊ณ Custom Hook์์ Typescript๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค.
React Hook ์ฌ์ฉ๊ฐ๋ ๋ณด๋ค๋ TypeScript๋ฅผ ์ ์ํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์ธํ ๋ค๋ฃจ๊ณ ์์ต๋๋ค.
2024.07.31 - [React] - ๋ฆฌ์กํธ useLayoutEffect ๊ฐ๋ ๋ฐ ์ฌ์ฉ๋ฒ
2024.08.02 - [React] - ๋ฆฌ์กํธ ์ ์ด vs ๋น์ ์ด ์ปดํฌ๋ํธ ์์๋ณด๊ธฐ
๐คทโ๏ธ React Hooks์ Typescript ์ค์ ์์
useState์ TypeScript
useState๋ ์ปดํฌ๋ํธ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ Hook์ ๋๋ค.
TypeScript๋ฅผ ์ฌ์ฉํ์ฌ ์ํ์ ํ์ ์ ๋ช ์์ ์ผ๋ก ์ง์ ํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ ์์
useState๋ฅผ ์ฌ์ฉํ ๋ ํ์ ์ ๋ช ์์ ์ผ๋ก ์ง์ ํ๋ฉด ์ํ์ ํ์ ์์ ์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ซ์ ์ํ๋ฅผ ๊ด๋ฆฌํ ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค
import React, { useState } from 'react';
const CounterComponent: React.FC = () => {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default CounterComponent;
๋ฌธ์์ด ์ํ ๊ด๋ฆฌ
๋ฌธ์์ด ์ํ๋ฅผ ๊ด๋ฆฌํ ๋๋ ํ์ ์ ๋ช ์์ ์ผ๋ก ์ง์ ํ ์ ์์ต๋๋ค
import React, { useState } from 'react';
const TextComponent: React.FC = () => {
const [text, setText] = useState<string>('');
return (
<div>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<p>{text}</p>
</div>
);
};
export default TextComponent;
๊ฐ์ฒด ์ํ ๊ด๋ฆฌ
๋ณต์กํ ๊ฐ์ฒด ์ํ๋ฅผ ๊ด๋ฆฌํ ๋๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ์ฌ ํ์ ์ ๋ช ์ํ ์ ์์ต๋๋ค
import React, { useState } from 'react';
interface User {
name: string;
age: number;
}
const UserComponent: React.FC = () => {
const [user, setUser] = useState<User>({ name: 'John', age: 30 });
return (
<div>
<p>User: {user.name}, Age: {user.age}</p>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>Increase Age</button>
</div>
);
};
export default UserComponent;
useEffect์ TypeScript
useEffect๋ ๋ถ์ ํจ๊ณผ(์ฌ์ด๋ ์ดํํธ)๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ, ๊ตฌ๋ ์ค์ , ์๋์ผ๋ก DOM ๋ณ๊ฒฝ ๋ฑ์ ์ฒ๋ฆฌํฉ๋๋ค.
์ฒซ ๋ ๋๋ง์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์์
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ useEffect๋ฅผ ์ฌ์ฉํ๋ฉด ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ๋ ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ธ๋ง์ดํธ๋ ๋ ์ ๋ฆฌ ์์ ์ ์ํํ ์ ์์ต๋๋ค
import React, { useEffect, useState } from 'react';
const DataFetchingComponent: React.FC = () => {
const [data, setData] = useState<string | null>(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data))
.catch(error => console.error('Error fetching data:', error));
return () => {
console.log('Cleanup on unmount');
};
}, []); // ๋น ๋ฐฐ์ด์ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋ ๋ ํ ๋ฒ๋ง ์คํ
return (
<div>
{data ? <p>Data: {data}</p> : <p>Loading...</p>}
</div>
);
};
export default DataFetchingComponent;
useContext์ TypeScript
useContext๋ Context API๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
Context๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ์ํ๋ฅผ ๊ณต์ ํ ์ ์์ต๋๋ค.
์์
์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด Context๋ฅผ ์์ฑํ๊ณ , ์ด๋ฅผ Provider์ Consumer๋ฅผ ํตํด ์ฌ์ฉํ ์ ์์ต๋๋ค
import React, { useContext, createContext, useState } from 'react';
// ์ฌ์ฉ์ ์ธํฐํ์ด์ค ์ ์
interface User {
name: string;
age: number;
}
// Context ์์ฑ
const UserContext = createContext<User | null>(null);
const UserProvider: React.FC = ({ children }) => {
const [user, setUser] = useState<User>({ name: 'John', age: 30 });
return (
<UserContext.Provider value={user}>
{children}
</UserContext.Provider>
);
};
const UserProfile: React.FC = () => {
const user = useContext(UserContext);
return (
<div>
{user ? <p>{user.name}, {user.age}</p> : <p>No user data</p>}
</div>
);
};
const App: React.FC = () => (
<UserProvider>
<UserProfile />
</UserProvider>
);
export default App;
useRef์ TypeScript
useRef๋ DOM ์์๋ ๋ค๋ฅธ ๊ฐ์ ์ฐธ์กฐํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์ฃผ๋ก ํฌ์ปค์ค ์ค์ ์ด๋ ๋ค๋ฅธ DOM ์กฐ์์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
์์
useRef๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ ฅ ์์์ ํฌ์ปค์ค๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค
import React, { useRef, useEffect } from 'react';
const FocusInputComponent: React.FC = () => {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
return <input ref={inputRef} type="text" />;
};
export default FocusInputComponent;
Custom Hook๊ณผ TypeScript
Custom Hook์ ์ฌ์ฉํ๋ฉด ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ก์ง์ ๋ถ๋ฆฌํ ์ ์์ต๋๋ค.
Custom Hook์ ์ผ๋ฐ ํจ์์ฒ๋ผ ๋์ํ๋ฉฐ, ๋ค๋ฅธ Hook์ ๋ด๋ถ์์ ํธ์ถํ ์ ์์ต๋๋ค.
์์
๋ค์ ์์ ์์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ Custom Hook์ ์ ์ํ๊ณ , ์ด๋ฅผ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค
import { useState, useEffect } from 'react';
const useFetch = <T,>(url: string): { data: T | null; loading: boolean } => {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setLoading(false);
});
}, [url]);
return { data, loading };
};
// ์ฌ์ฉ ์์
import React from 'react';
interface UserData {
id: number;
name: string;
}
const UserFetchComponent: React.FC = () => {
const { data, loading } = useFetch<UserData>('https://api.example.com/user');
return (
<div>
{loading ? <p>Loading...</p> : data ? <p>{data.name}</p> : <p>No Data</p>}
</div>
);
};
export default UserFetchComponent;
๐คทโ๏ธ React ๊ฐ๋ฐ์๋ฅผ ์ํ TypeScript์ Hooks ์ฌ์ฉ ํ ๋ฐ ์์ ๋ง์ง๋ง์ผ๋ก
๋ฆฌ์กํธ ํ ์ ํ์ ์คํฌ๋ฆฝํธ์ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ฝ๋์ ํ์ ์์ ์ฑ์ ๋์ด๊ณ ์ ์ง๋ณด์์ฑ์ ๊ฐ์ ํฉ๋๋ค.
๋ฐ๋๋ก, ํ์ ์์ ์ฑ์ ๋์ด๊ณ ์ ์ง ๋ณด์์ฑ์ ๋์ด๋ ค๋ฉด ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ ๋ค๋ค์ผ ํ๋ฉฐ ๋ง์ ๊ณต๋ถ๊ฐ ํ์ํฉ๋๋ค.
์ด ๊ธ์์ ๊ธฐ๋ณธ์ ์ธ ๋ฆฌ์กํธ ํ useState, useEffect, useContext, useRef ๊ทธ๋ฆฌ๊ณ Custom Hook์ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ํ๊ณ ํ์ ์์ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ดค์ต๋๋ค.
์ฌ๋ฐ๋ ์ค๋์ ๋ ๋ณ ์ด์ธ ๋ณด๊ณ ๊ฐ์ธ์!
https://cometruedream.tistory.com/247
https://cometruedream.tistory.com/243
https://cometruedream.tistory.com/242
https://cometruedream.tistory.com/241
https://cometruedream.tistory.com/244
'React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ด๋ฆฌ์๋จ ํ์ ๊ธฐ๋ฅ react-csv ํ์ฉํ CSV ํ์ผ ๋ค์ด๋ก๋ (1) | 2024.08.22 |
---|---|
NextJS์์ Prisma๋ฅผ ์ฌ์ฉํ Vercel์ ๋ฐฐํฌ ์ค๋ฅ ํด๊ฒฐ ๋ฐฉ๋ฒ (2) | 2024.08.09 |
๋ฆฌ์กํธ ์ ์ด vs ๋น์ ์ด ์ปดํฌ๋ํธ ์์๋ณด๊ธฐ (0) | 2024.08.02 |
๋ฆฌ์กํธ useLayoutEffect ๊ฐ๋ ๋ฐ ์ฌ์ฉ๋ฒ (36) | 2024.07.31 |
[React-query] ๋ฐ์ดํฐํต์ ์ ์ํ useMutation ๊ฐ๋ ๊ณผ hooks ์ฌ์ฉ๋ฒ (29) | 2024.07.16 |