Frontend

기본 Hook에 대해서

단점이없어지고싶은개발자 2022. 4. 17. 20:13
반응형

useState

const [state, setState] = useState(initialState);

상태 유지 값과 그 값을 갱신하는 함수를 반환한다.

최초로 렌더링 하는 동안, 반환된 state는 첫 번째 전달된 초기값의 값과 같다.

setState함수는 state를 갱신할 때 사용한다. 새 state 값을 받아 컴포넌트 리렌더링을 큐에 등록한다.

다음 리렌더링 시에 useState를 통해 반환받은 첫 번째 값은 항상 갱신된 최신 state가 된다.

React는 setState 함수 동일성이 안정적이고 리렌더링 시에도 변경되지 않을 것이라는 것을 보장한다.

업데이트 함수가 현재 상태와 정확히 동일한 값을 반환한다면 바로 뒤에 일어날 리렌더링은 완전히 건너뛰게 된다.

팁!

useState는 갱신 객체를 자동으로 합치지는 않는다. 함수 업데이터 폼을 객체 전개 연산자과 결합함으로써 이 동작을 복제할 수 있다

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

리액트는 Object.is 비교 알고리즘을 사용한다. 두 인수가 같은 값인지 여부를 나타내는 Boolean

렌더링 시에 고비용의 계산을 하고 있다면 useMemo를 사용해서 최적화를 해준다.

useEffect

useEffect(didUpdate);

명령형 또는 어떤 effect를 발생하는 함수를 인자로 받는다.

변형, 구독, 타이머, 로깅 또는 다른 부작용(side Effect)은 함수 컴포넌트의 본문 안에서는 허용되지 않는다. 만약 수행한다면 혼란스러운 버그 및 UI의 불일치가 일어날 것이다.

useEffect에 전달된 함수는 화면에 렌더링이 완료된 후에 수행되게 될 것이다.

effect는 종종 컴포넌트가 화면에서 제거될 때 정리해야 하는 리소스를 만든다. useEffect로 전달된 함수는 정리함수를 반환할 수 있다.

정리함수는 메모리 누수 방지를 위한 UI에서 컴포넌트를 제거하기전에 수행된다. 여러번 렌더링 된다면 다음 effect가 수행되기 전에 이전 effect는 정리된다.

useEffect로 전달된 함수는 지연 이벤트동안에 레이아웃 배치와 그리기를 완려된 후 발생한다. 이것은 구독이나 이벤트 핸드러를 설정하는 것과 같은 다수의 공통적인 부작용에 적합하다. 왜냐면 대부분의 작업이 브라우저에서 화면을 업데이트하는 것을 차단해서는 안되기 때문이다.

useEffect는 브라우저에 화면이 다 그려질 때까지 지연되지만, 다음 어떤 새로운 렌더링이 발생하기 이전에 발생되는 것도 보장한다.

effect의 기본 동작은 모든 렌더링을 완료 후 effect를 발생하는 것이다. 의존성 중 하나가 변경된다면 effect는 항상 재생성된다.

useContext

const value = useContext(MyContext);

props drilling이 깊어지는것을 막고자 사용한 Hook

props를 통한 전달이 아닌 context를 이용해서 공유한다.

context API를 사용하기 위해서는 Provider, Consumer, createContext

  • Provider : 생성한 context를 하위 컴포넌트에게 전달하는 역할을 한다.
  • Consumer : context의 변화를 감시하는 컴포넌트이다.
  • creteContext : context 객체를 생성한다.
import React, { createContext } from "react";
import Children from "./Children";

// AppContext 객체를 생성한다.
export const AppContext = createContext();

const App = () => {
  const user = {
    name: "김채원",
    job: "가수"
  };

  return (
    <>
      <AppContext.Provider value={user}>
        <div>
          <Children />
        </div>
      </AppContext.Provider>
    </>
  );
};

export default App;
import React from "react";
import { AppContext } from "./App";

const Children = () => {
  return (
      <AppContext.Consumer>
        {(user) => (
          <>
            <h3>AppContext에 존재하는 값의 name은 {user.name}입니다.</h3>
            <h3>AppContext에 존재하는 값의 job은 {user.job}입니다.</h3>
          </>
        )}
      </AppContext.Consumer>
  );
};

export default Children;

useReducer

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

useState의 대체 함수다. (state, action) ⇒ newState의 형태로 reducer을 받고 dispatch메서드와 짝의 형태로 현재 state를 반환한다. (Redux에 익숙하다면 이것이 어떻게 동작하느지 여러분은 이미 알고 있을 것입니다.)

React는 dispatch 함수의 동일성이 안정적이고 리렌더링 시에도 변경되지 않으리라는 것을 보장한다. 이것이 useEffect나 useCallback 의존성 목록에 이 함수를 포함하지 않아도 괜찮은 이유다.

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

메모이제이션된 콜백을 반환한다.

인라인 콜백과 그것의 의존성 값의 배열을 전달한다. useCallback은 콜백의 메모이제이션된 버전을 반환할 것이다. 그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경된다. 불필요한 렌더링을 방지하기 위해 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용하다.

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

생성함수와 그것의 의존성 값의 배열을 전달. useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산 한다. 모든 렌더링 시의 고비용 계산을 방지하게 해준다.

배열이 없다면 매 렌더링 때마다 새 값을 계산한다.

반응형