
이제 이틀뒤면 프론트엔트 파트의 교육이 끝나게된다.
오늘까지 배운 React에서 사용되는 Hook에 대해 정리해보자.
클래스형 컴포넌트에서 제공하는 기능을 함수형 컴포넌트에서 사용할 수 있도록 도입된 함수이다.
접두어는 use를 사용한다.
함수형 컴포넌트 내부에서 상태를 정의하고, 상태를 관리할 수 있게 해주는 훅이다.
const [state, setState] = useState(initialValue);
정확히 말하자면 컴포넌트에 side-effect 를 부여하기 위한 훅이지만, 쉽게 이해하기 위해서는 컴포넌트의 생명주기 메서드를 대체하기 위한 훅이라고 이해해도 괜찮을 것 같다.
useEffect(()=>{
// side-effect 로직
return () => {
//cleanup
}
},[dependencies])
DOM 요소에 직접 접근하거나, 상태 변화와 관계없이 값을 유지하기 위한 Hook.
ref.current 로 접근한다.
const ref = useRef(initialValue);
function InputFocus(){
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return(
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
상태와 상태 변경 로직을 관리하기 위한 Hook. 복잡한(다수의) 상태 로직이 필요한 경우 유용함.
const [state, dispatch] = useReducer(reducer, initialState);
const initialState={count:0}
function reducer(state, action){
switch (action.type) {
case 'increment':
return {count: state.count + 1}
case 'decrement':
return {count: state.count - 1}
default:
return state;
}
}
function Counter(){
const [state,dispatch] = useReducer(reducer, initialState);
return(
<div>
<p>Count: {state.count}</p>
<button onClick={()=>dispatch({type:'increment'})>+</button>
<button onClick={()=>dispatch({type:'decrement'})>-</button>
</div>
);
}
성능 최적화를 위해 계산된 값을 메모이제이션하는 Hook. 의존성배열이 변경될때만 재계산이 이루어짐.
const memoizedValue = useMemo(()=> computeExpensiveValue(a,b),[a,b]);
function ExpensiveCalculation({num}){
const compute = (n) => {
console.log("calulating...")
return n*n;
);
const result = useMemo(()=>compute(num),[num]);
return <div>{result}</div>
}
성능 최적화를 위해 콜백 함수 메모이제이션을 위해 사용됨. 동일한 함수의 재생성을 방지함.
const memoizedCallback = useCallback(()=>{
},[dependencies]);
function Counter(){
const [count, setCount] = useState(0);
const increment = useCallback(()=>{
setCount((prevCount) => prevCount+1);
},[]);
return(
<div>
<p>{count}</p>
<button onClick={increment}>Increment</button>
</div>
React의 Context API를 사용하여 상태변수를 전역에서 관리할 수 있다.
Context를 사용할 범위를 Context의 Provider로 감싸주어야한다.
value로 전달하는 값은 전역에서 관리할 초기 상태값이다.
쉽게 말해 중첩없이 상태를 구독할 수 있다.
const value = useContext(MyContext);
const ThemeContext = createContext();
function ThemeButton() {
const Theme = useContext(ThemeContext);
return <button style = {{ background: theme}}>Themed Button</button>;
}
function App(){
return(
<ThemeContext.Provider value="light">
<ThemedButton/>
</ThemeContext.Provider>
)
}
여러 컴포넌트에서 재사용 가능한 로직을 추출하여 관리하는 방법
커스텀 Hook은 우리가 state 그 자체가 아닌 state 저장 로직을 공유하도록 해줍니다. 같은 Hook을 호출하더라도 각각의 Hook 호출은 완전히 독립되어 있습니다.
커스텀 훅을 사용한다면 코드 재사용성을 높일 수 있다.
상태를 관리하는 코드를 만드는 것이기 때문에 useState 및 useReducer를 사용할 수 있다. 복수개이면 반복문으로 useState를 정의하거나, useReducer를 사용하는 것이 좋을 것 같다.
const useCustomHook = (initialValue) => {
const [state,setState] = useState(initialValue);
// 로직
const inputProps = {value: value,onChange: handleChange}
// 상태를 반환
return inputProps
}
export function useFormInput(initialValue) {
const [value, setValue] = useState(initialValue);
function handleChange(e) {
setValue(e.target.value);
}
const inputProps = {
value: value,
onChange: handleChange
};
return inputProps;
}
export default function Form() {
const firstNameProps = useFormInput('Mary');
const lastNameProps = useFormInput('Poppins');
return (
<>
<label>
First name:
<input {...firstNameProps} />
</label>
<label>
Last name:
<input {...lastNameProps} />
</label>
<p><b>Good morning, {firstNameProps.value} {lastNameProps.value}.</b></p>
</>
);
}
훅 들어 오시네요.. 정말 깜짝 놀랄만한 포스팅입니다. 저는 기절직전에 눈팅왔습니다. 체력이 조달려 운동시작합니다. 안녕히 주무세요