React Hook 1

jinabbb·2022년 10월 20일
0

react hook

목록 보기
1/2

React Hook 정리하기 1

요즘 그냥 useState useEffect만 사용해서 효율적이지 않은 개발을 하고 있지 않은것 같아 유용한 hook들을 한 번 정리해서 사용하려고 한다.

정리하는 김에 알던것도 좀 더 깊게 다시 한번 정리해보자

useState

조건문 , 루프문 등에 들어갈 수 없다. 함수 최상위에서만 사용가능하다.

항상 state와 state를 업데이트 할 수 있는 함수(setState)로 이루어진 배열을 리턴한다.

setState함수를 통해 state를 업데이트 할 때 기존의 state값을 참조하고 싶다면

setState함수에 인자로 콜백함수를 넘겨준다. ⇒ 콜백함수를 쓰지 않고 기존의 state를 그냥 참조해서 쓴다면 바뀐 state를 보장해주지 못한다.

콜백함수의 인자: 이전 상태

콜백함수의 리턴: 상태로 바뀔 값

컴포넌트가 렌더링 될 때 마다 useState를 호출하는데 초기값 구하는게 복잡하다면 성능이 좋지 않다. ⇒ useState에 콜백함수를 넣어주면 컴포넌트가 처음 렌더링 될때만 실행된다.

useEffect

class component의 lifecycle method들 대신 useEffect로 모두 처리한다.

첫번째 인자 : 실행될 함수

두번째 인자: 변경을 감지할 상태들의 배열

두번쨰 인자에 빈 배열을 준다면 처음 렌더링 될때만 함수를 실행한다.

실행할 함수에 콜백함수를 리턴하면 컴포넌트가 언마운트 될때 실행한다. (클린업 함수)

useEffect훅 안에서 외부함수를 사용할 경우 missing dependency 경고가 뜨는데, 이는 외부 함수는 렌더링 될때마다 재정의 되어 변할 수 있기 때문이다.

웬만하면 useEffect함수 안에서 정의해서 사용하자.

useContext

React.createContext()로 context를 만든다.

Provider의 value props에 하위 컴포넌트에서 사용할 수 있는 상태 값을 넣어준다.

하위 컴포넌트에서는 useContext훅을 이용하여 value를 사용할 수 있다.

//ThemeContext.jsx
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();
const ThemeUpdateContext = createContext();

export function useTheme() {
	return useContext(ThemeContext);
}

export function useThemeUpdate() {
	return useContext(ThemeUpdateContext);
}

export function ThemeProvider({ children }) {
	const [darkTheme, setDarkTheme] = useState(true);

	function toggleTheme() {
		setDarkTheme((prev) => !prev);
	}

	return (
		<ThemeContext.Provider value={darkTheme}>
			<ThemeUpdateContext.Provider value={toggleTheme}>{children}</ThemeUpdateContext.Provider>
		</ThemeContext.Provider>
	);
}

//Context.jsx
import { useTheme, useThemeUpdate } from '../context/ThemeContext';
const Context = () => {
	const darkTheme = useTheme();
	const toggleTheme = useThemeUpdate();
	const themeStyles = {
		backgroundColor: darkTheme ? '#333' : '#ccc',
		color: darkTheme ? '#ccc' : '#333',
		padding: '2rem',
		margin: '2rem',
	};
	return (
		<>
			<button onClick={toggleTheme}>Toggle Theme</button>
			<div style={themeStyles}>Function Theme</div>
		</>
	);
};
export default Context;

useRef

useState와 사용하는게 비슷하지만 큰 차이는 ref는 값이 변경되도 컴포넌트를 리렌더링하지 않는다.

useMemo

컴포넌트의 상태가 바뀌면 리렌더링 되면서 코드들을 실행하는데 이 때 값이 바뀌지 않는 객체들을 캐싱하여 다시 연산하지 않기 위해 사용.

변수도 객체나 배열의 경우 다시 실행되면 같은 레퍼런스가 아니기 때문에 useMemo훅을 이용해서 할당하면 불필요한 함수 호출을 막을 수 있다.

import React, { useEffect, useMemo, useState } from 'react';

const Memo = () => {
	const [number, setNumber] = useState(0);
	const [dark, setDark] = useState(false);
	const doubleNumber = useMemo(() => {
		return slowFunction(number);
	}, [number]);

	const themeStyles = useMemo(() => {
		return {
			backgroundColor: dark ? 'black' : 'white',
			color: dark ? 'white' : 'black',
		};
	}, [dark]);

	useEffect(() => {
		console.log('themeStyles changed');
	}, [themeStyles]);

	return (
		<>
			<input type='number' value={number} onChange={(e) => setNumber(parseInt(e.target.value))} />
			<button
				onClick={() => {
					setDark((prev) => !prev);
				}}
			>
				Change Theme
			</button>
			<div style={themeStyles}>{doubleNumber}</div>
		</>
	);
};

function slowFunction(num) {
	for (let i = 0; i < 1000000000000; i++) {}
	return num * 2;
}

export default Memo;

useCallback

useMemo와 거의 같은 개념이다. 컴포넌트가 리렌더링 될 때 함수도 다시 정의 되는데 useCallback훅의 디펜던시가 바뀔때만 다시 정의하도록 하는 훅이다.

import React, { useEffect, useState, useCallback } from 'react';

const List = ({ getItems }) => {
	const [items, setItems] = useState([]);
	useEffect(() => {
		setItems(getItems());
		console.log('Updating Items');
	}, [getItems]);
	return items.map((item) => <div key={item}>{item}</div>);
};

const Callback = () => {
	const [number, setNumber] = useState(1);
	const [dark, setDark] = useState(false);

	const getItems = useCallback(() => {
		return [number, number + 1, number + 2];
	}, [number]);

	const theme = {
		backgroundColor: dark ? '#333' : '#fff',
		color: dark ? '#fff' : '#333',
	};

	return (
		<div style={theme}>
			<input type='number' value={number} onChange={(e) => setNumber(parseInt(e.target.value))} />
			<button
				onClick={() => {
					setDark((prev) => !prev);
				}}
			>
				Toggle theme
			</button>
			<List getItems={getItems}></List>
		</div>
	);
};

export default Callback;

거의 대표적으로 쓰는 6개훅이다.

그외의 useReducer, useTransition, useDefferredValue, useLayoutEffect, useDebugValue, useImperativeHandle, useId, Custom Hook도 나중에 다룰것이다.

profile
개발

0개의 댓글