Hook ๊ฐ์
- Hook์ class๋ฅผ ์์ฑํ์ง ์๊ณ ๋ state์ ๋ค๋ฅธ React์ ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค
- Hook์ ๊ณ์ธต์ ๋ณํ ์์ด ์ํ ๊ด๋ จ ๋ก์ง์ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ๋์์ค
๊ธฐ๋ณธ Hook
- useState
- useEffect
- useContext
์ถ๊ฐ Hooks
- useReducer
- useCallback
- useMemo
- useRef
- useImperativeHandle
- useLayoutEffect
- useDebugValue
- useDeferredValue
- useTransition
- useId
library hooks
- useSyncExternalStore
- useInsertionEffect
๐State Hook
์ฌ๋ฌ state ๋ณ์ ์ ์ธํ๊ธฐ
ํ๋์ ์ปดํฌ๋ํธ ๋ด์์ state hook์ ์ฌ๋ฌ๊ฐ ์ฌ์ฉํ ์ ์์
function ExampleWithManyStates() {
// ์ํ ๋ณ์๋ฅผ ์ฌ๋ฌ ๊ฐ ์ ์ธ
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
HOOK์ด๋?
- ํจ์ ์ปดํฌ๋ํธ์์ React state์ ์๋ช ์ฃผ๊ธฐ ๊ธฐ๋ฅ์ ์ฐ๋ ํ ์ ์๊ฒ ํด์ฃผ๋ ํจ์
- class ์์์๋ ๋์ํ์ง ์์
โก๏ธ Effect Hook
- useEffect๋ ํจ์ ์ปดํฌ๋ํธ ๋ด์์ ์ด๋ฐ side effects๋ฅผ ์ํํ ์ ์๊ฒ ํจ
- React class์ componentDidMount๋ componentDidUpdate, componentWillUnmount์ ๊ฐ์ ๋ชฉ์ ์ผ๋ก ์ ๊ณต๋๋ ๊ฒ์ ํ๋์ API๋ก ํตํฉ
- ์ค์ต
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate์ ๋น์ท
useEffect(() => {
// ๋ธ๋ผ์ฐ์ API๋ฅผ ์ด์ฉํด ๋ฌธ์์ ํ์ดํ์ ์
๋ฐ์ดํธ!
document.title = `clicked ${count} times`;
});
return (
<div>
<p>clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
click
</button>
</div>
);
}
- Effect ํด์
- ํจ์๋ฅผ ๋ฐํ (optional)
- ex) ์ปดํฌ๋ํธ - ์น๊ตฌ์ ์ ์ ์ํ๋ฅผ ๊ตฌ๋ ํ๋ effect ์ฌ์ฉ⇒ ๊ตฌ๋ ์ ํด์งํจ์ผ๋ก์จ ํด์
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); };
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
- useEffect ์ปดํฌ๋ํธ ๋ด์์ ์ฌ๋ฌ ๊ฐ์ effect๋ฅผ ์ฌ์ฉ ํ ์ ์์
- Hook์ ์ฌ์ฉํ๋ฉด ๊ตฌ๋
์ ์ถ๊ฐํ๊ณ ์ ๊ฑฐํ๋ ๋ก์ง๊ณผ ๊ฐ์ด ์๋ก ๊ด๋ จ ์๋ ์ฝ๋๋ค์ ํ๊ตฐ๋ฐ์ ๋ชจ์์ ์์ฑ
- class ์ปดํฌ๋ํธ์์๋ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋(lifecycle methods) ๊ฐ๊ฐ์ ์ชผ๊ฐ์ ๋ฃ์ด์ผ ํจ
โ๏ธHOOK ์ฌ์ฉ ๊ท์น
- ์ต์์์์๋ง ํธ์ถ
- ๋ฐ๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค์ฒฉ๋ ํจ์ ๋ด์์ hook ์คํ ๊ธ์ง
- React ํจ์ ์ปดํฌ๋ํธ ๋ด์์๋ง hook์ ํธ์ถ
- ์ผ๋ฐ js ํจ์์์๋ hook์ ํธ์ถ ํ๋ฉด ์๋จ
State Hook ์ฌ์ฉํ๊ธฐ
Hook์ด๋?
- React์ useState Hook
import React, { useState } from 'react';
function Example() {
// ...
}
state ๋ณ์ ์ ์ธํ๊ธฐ
- class๋ฅผ ์ฌ์ฉํ ๋
- constructor์์ this.state๋ฅผ {count:0} ๋ก ์ค์
- count๋ฅผ 0์ผ๋ก ์ด๊ธฐํ
class Exam extends React.component{ constructor(props){ super(props) this.state={ count:0 } }
- ํจ์ํ ์ปดํฌ๋ํธ
- this๋ฅผ ๊ฐ์ง ์ ์์ ⇒ this.state๋ฅผ ํ ๋นํ๊ฑฐ๋ ์ฝ์ ์ ์์
- useState Hook์ ์ง์ ์ปดํฌ๋ํธ์ ํธ์ถ
import React, { useState } from 'react'; function Example() { // ์๋ก์ด state ๋ณ์๋ฅผ ์ ์ธํ๊ณ , ์ด๊ฒ์ count๋ผ ๋ถ๋ฅด๊ฒ ์ต๋๋ค. const [count, setCount] = useState(0);
state ๊ฐ์ ธ์ค๊ธฐ
- ํด๋์ค ์ปดํฌ๋ํธ
- this.state.count ์ฌ์ฉ
<p>You clicked {this.state.count} times</p>
- ํจ์ํ ์ปดํฌ๋ํธ
- count ์ง์ ์ฌ์ฉ
<p>You clicked {count} times</p>
state ๊ฐฑ์ ํ๊ธฐ
- ํด๋์ค ์ปดํฌ๋ํธ
- this.setState() ํธ์ถ
<button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me </button>
- ํจ์ํ ์ปดํฌ๋ํธ
- setCount์ count ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก this๋ฅผ ํธ์ถํ์ง ์์๋ ๋จ
<button onClick={() => setCount(count + 1)}> Click me </button>
Effect Hook ์ฌ์ฉํ๊ธฐ
- ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ, ๊ตฌ๋ (subscription)์ค์ ํ๊ธฐ, ์๋์ผ๋ก React ์ปดํฌ๋ํธ์ DOM์ ์์ ํ๋ ๊ฒ
- class ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋์์ componentDidMount์ componentDidUpdate, componentWillUnmount๊ฐ ํฉ์ณ์ง ๊ฒ
Hook์ ์ฌ์ฉํ๋ ์์
- useEffect๊ฐ ํ๋ ์ผ์?
- React์๊ฒ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ์ดํ์ ์ด๋ค ์ผ์ ์ํํ๋๊ฐ
- ์ฐ๋ฆฌ๊ฐ ๋๊ธด ํจ์(effect)๋ฅผ ๊ธฐ์ตํ๋ค๊ฐ DOM ์ ๋ฐ์ดํธ๋ฅผ ์ํํ ์ดํ์ ๋ถ๋ฌ๋
- useEffect๋ฅผ ์ปดํฌ๋ํธ ์์์ ๋ถ๋ฌ๋ด๋ ์ด์ ๋?
- ์ปดํฌ๋ํธ ๋ด๋ถ์ ๋ ์ผ๋ก์จ effect๋ฅผ ํตํด count state ๋ณ์(๋๋ ์ด๋ค prop)์ ์ ๊ทผํ ์ ์์
- ํจ์ ๋ฒ์์์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ํน๋ณํ API ์์ด๋ ๊ฐ์ ์ป์ ์ ์์
- hook์ ์๋ฐ์คํฌ๋ฆฝํธ์ ํด๋ก์ ๋ฅผ ์ด์ฉํ์ฌ react์ ํ์ ๋ API๋ฅผ ๊ณ ์ํ๋ ๊ฒ๋ณด๋ค ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ์ด๋ฏธ ๊ฐ์ง๊ณ ์๋ ๋ฐฉ๋ฒ์ ์ด์ฉํด ๋ฌธ์ ํด๊ฒฐ
- useEffect๋ ๋ ๋๋ง ์ดํ์ ๋งค๋ฒ ์ํ?
- ๊ธฐ๋ณธ์ ์ผ๋ก ์ฒซ๋ฒ์งธ ๋ ๋๋ง๊ณผ ์ดํ์ ๋ชจ๋ ์ ๋ฐ์ดํธ์์ ์ํ
- effect๊ฐ ์ํ๋๋ ์์ ์ ์ด๋ฏธ DOM ์ด ์ ๋ฐ์ดํธ
Effect ์ ๋ฆฌ
- ํ์ํ ๊ฒฝ์ฐ
- ํจ์๋ฅผ ๋ฐํ
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
- ํ์ ์๋ ๊ฒฝ์ฐ
- ๋ฐํํ์ง ์์
useEffect(() => {
document.title = `You clicked ${count} times`;
});
Effect์ ์ต์ ํ
- useEffect Hook API์ ๋ด์ฌํ
- ํน์ ๊ฐ๋ค์ด ๋ฆฌ๋ ๋๋ง ์์ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด, react๋ก ํ์ฌ๊ธ effect ๊ฑด๋ ๋ธ ์ ์์
- useEffect ์ ์ ํ์ ์ธ์์ธ ๋ ๋ฒ์งธ ์ธ์๋ก ๋ฐฐ์ด์ ๋๊น
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // count๊ฐ ๋ฐ๋ ๋๋ง effect๋ฅผ ์ฌ์คํํฉ๋๋ค.
useContext
- Context๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ญ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ณต์
- ์ค๊ฐ ๋ค๋ฆฌ ์ญํ ๋ง ํ๋ ์ปดํฌ๋ํธ๋ค์ ๊ฑด๋๋ฐ๊ณ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ปดํฌ๋ํธ์์ ๋ฐ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅ
- ๋ฆฌ์กํธ Hook์ธ useContext๋ ์ด๋ฌํ Context๋ฅผ ์ข ๋ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ์ญํ
- useContext๋ก ์ ๋ฌํ ์ธ์๋ context ๊ฐ์ฒด ๊ทธ ์์ฒด์ด์ด์ผ ํจ
import HeaderBar from '../components/header/HeaderBar'
import React,{useState,useEffect, useContext} from'react'
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
const [count, setCount] = useState(0)
useEffect(()=>{
document.title = `clicked ${count} times`
})
return (
<div className="App">
<HeaderBar/>
<p>clicked {count} times</p>
<button onClick={()=>setCount(count+1)}>
click
</button>
**<ThemeContext.Provider value={themes.dark}>
<Tool/>
</ThemeContext.Provider>**
</div>
);
}
function Tool(props){
return(
<div>
<ThemedButton/>
</div>
)
}
function ThemedButton(){
const theme = useContext(ThemeContext)
return(
<button style={{background:theme.background,color:theme.foreground}}>
theme context
</button>
)
}
export default App;
'Development > React.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] ref, useRef (0) | 2023.01.24 |
---|---|
[React] port ๋ฒํธ ๋ณ๊ฒฝํ๊ธฐ (0) | 2023.01.23 |
[React] React Life Cycle ; ๋ฆฌ์กํธ ์๋ช ์ฃผ๊ธฐ (0) | 2023.01.14 |
SPA / CSR / TTI / TTV / SEO / Metaํ๊ทธ / Opengraph (0) | 2022.10.14 |
์ํฐ๋ ํ๋ฆฌ์จ๋ณด๋ฉ ์ฑ๋ฆฐ์ง ์ฌ์ ๊ณผ์ (CSR / SSR with Next.js) (0) | 2022.09.28 |
๋๊ธ