React Hook

최정환·2021년 11월 10일
0

React

목록 보기
3/7

Hook

hook이 나오게 된 동기

  1. 컴포넌트 사이에서 상태 로직을 재사용하기 어렵다.
  2. 복잡한 컴포넌트들은 이해하기 어렵다.
  3. class는 사람과 기계를 혼동시킨다.

나온 이유를 간단하게 생각해보면 함수형 컴포넌트를 더 사용하기 쉽게 만들기 위해 장점을 더 살리기 위해 나왔다고 보는게 맞다.

hook이란

hook은 함수 컴포넌트에서 React state와 생명주기 기능을 연동할 수 있게 해주는 함수
hook은 class 안에서는 동작하지 않는다.

useState

state hook이며 상태를 관리하는데 사용하는 hook이다.

const [count, setCount] = useState(0)

위와 같이 변수를 선언하고 기본값을 설정할 수 있다.

state : count
state의 setter : setCount
state의 기본값 : useState의 인자값

setter를 사용하여 state의 값을 바꿀 수 있다.

만약 state가 갱신된다면 rerendering이 일어난다.

https://ko.reactjs.org/docs/hooks-state.html


useEffect

Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있다.
React는 effect가 수행되는 시점에 이미 DOM이 업데이트되었음을 보장한다.

  1. 하는일
    rendering 이후에 어떤 일을 수행하는지을 말할 수 있다.
    React는 이곳에 넘긴 함수를 기억하고 있다가 DOM 업데이트 이후(state 변경) 불러낼 것이다.

  2. 컴포넌트 안에서 불러내는 이유
    컴포넌트 안에 존재하는 상태 변수에 접근이 가능하기 때문이다.

  3. 렌더링 이후에 매번 수행될까?
    기본적으로 첫번째 렌더링(마운트)과 이후 모든 업데이트에서 수행된다.
    마운팅과 업데이트라는 방식으로 생각하는 대신 effect를 렌더링 이후에 발생하는 것으로 생각하는게 쉽다.
    deps를 통해 특정 상태가 변할때만 rerendering이 발생하도록 최적화가 가능하다.

🔔 예제

1번 console.log는 한번만 실행
2번 console.log는 state가 변하거나 새로고침 등 함수가 재실행될때마다 실행된다.
3번은 keyword가 변화할때마다 실행함. Deps에 들어가는 변수는 그 변수를 눈여겨봐 달라고 하는것과 같다.
Deps안에는 한개이상의 변수가 들어갈 수 있다.

function App(){
  const [co,setCo] = useState(0);
  const [keyword,setKeyword] = useState("");
  const onClick = ()=>setCo((prev)=>prev+1);
  const onChange = (event) => setKeyword(event.target.value);
  // 2 
  console.log("Run Every Time")
  // 1
  const iRunOnlyOnce =()=>{
    console.log("Run Only Once");
  }
  useEffect(iRunOnlyOnce,[])
  // 3
  useEffect(()=>{console.log("Search",keyword)},[keyword])
  
  return (
  	<div>
    <input value={keyword} onChange={onChange} type="text"/>
    <h1>{co}</h1>
	<button onClick={onClick}>click</button>
    </div>
  )
}

🔔 Clean up

외부 데이터에 구독을 설정해야하는 경우 effect를 cleanup해야하는 경우도 있다. (보통 API)
이런 경우에 만약 cleanup을 하지 않는다면 메모리 누수가 발생한다.
따라서 side effect를 멈춰야할때 사용한다.

간단하게 라이프 사이클로 설명하자면

컴포넌트가 언마운트 되었을때 실행했던 함수를 죽이고 싶다. 이때 cleanup을 사용한다.

function FriendStatus(props) {
  // ...
  useEffect(() => {
    // ...
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });


추가 Hook

위의 훅들은 기본적인 훅으로 저 2개만 있어도 리액트로 웹을 만들 수 있다.
지금부터 나오는 훅들은 기본 훅의 변경이거나 특정한 경우에만 필요한 것이다.

useReducer

useState의 대체 함수.
형태 : (state, action) => newState

const [state, dispatch] = useReducer(reducer, initialArg, init);

state : 상태

dispatch : action에 사용할 type을 인자로 사용한다.

reducer : (state, action)을 인자로 하는 함수로 action.type에 따른 로직을 구현한다. 반환값은 initailArg를 기준으로 한 값

initialArg : state가 가지는 초기값이다. 이 값을 기준으로 state 값이 설정된다.

init : 초기화 지연을 위해 사용한다.


// init 사용 x 경우
const initialState = {count: 0};

// init 사용 경우
function init(initialState) {
  return {count: initialState};
}

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'reset' :
      return init(action.payload)
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState, init);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

memozation

useMemo와 useCallback


useRef

.current 속성으로 전달된 인자로 초기화된 변경 가능한 ref 객체를 반환한다.
useRef는 리렌더링을 하지 않고 컴포넌트 속성만 조회&수정한다.

이 기능은 클래스에서 인스턴스 필드를 사용하는 방법과 유사한 어떤 가변값을 유지하는데 편리하다.

반환된 객체는 컴포넌트의 전 생애주기를 통해 유지된다.

const ref = useRef(initialValue)

본질적으로 useRef는 변경 가능한 값을 담고 있는 상자와 같다.

일반적으로 DOM 요소를 특정하고 조작하는데 사용한다.
element의 ref에 접근할 수 있는 시점은 React Node가 실제 DOM에 반영되는 시점부터다.

따라서 useRef를 사용해서 접근하나 DOM API(selector)를 사용해서 접근해도 같은 결과값이 나온다.
그러면 왜 실제 DOM API를 사용하면 안될까?

ref가 특정 요소를 가져올 때 더 신뢰성이 있기 때문이다.
만약 예상치 못한 상황에 의해 DOM API를 이용해 요소를 가져오지 못한다면 큰 버그를 일으킬 수 있다.

참고:
https://ko.reactjs.org/docs/hooks-reference.html

https://tecoble.techcourse.co.kr/post/2021-05-15-react-ref/

0개의 댓글