ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL_200922(React Hook API)
    카테고리 없음 2020. 9. 23. 02:24

     

     

    기본 Hook

     

    useState

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

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

    최초의 state 값은 첫 번째 전달된 인자인 initialState의 값과 같습니다.

     

    state 값을 갱신하는 경우

    setState(newState);

     

     

    함수적 갱신

    function Counter({initialCount}) {
      const [count, setCount] = useState(initialCount);
      return (
        <>
          <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
        </>
      )

    갱신된 값이 이전의 값(prevCount)을 바탕으로 계산됩니다.

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

     

     

    지연 초기 state

    initialState 인자는 초기 렌더링 시에 사용하는 state입니다. 그 이후 렌더링 시에는 이 값은 무시됩니다.

    만약에 초기 state가 고비용 계산의 결과하면 초기 렌더링 시에만 실행될 함수를 제공할 수 있습니다.

    const [state, setState] = useState(() => {
      const initialState = someExpensiveComputation(props);
      return initialState;
    });

     

     

    state 갱신의 취소

    State Hook을 현재의 state와 동일한 값으로 갱신하는 경우 React는 렌더링이나 실행을 회피하고 처리를 종료합니다.

    실행을 회피하기 전에 특정 컴포넌트를 렌더링하는 것이 여전히 필요할 수 있다는 것을 주의합니다.

     

     

    useEffect

    useEffect(didUpdate);

    어떤 effect를 발생하는 함수를 인자로 받습니다.

    side effects는 함수 컴포넌트 안에서 허용되지 않습니다. 대신에 useEffect를 사용하게 됩니다.

    useEffect에 전달된 함수는 화면이 렌더링된 후에 실행됩니다. 그리고 어떤 값이 변경되었을 때에만 실행될 수도 있습니다.

     

    effect 정리

    effect는 종종 컴포넌트가 화면에서 제거될 때 정리해야 하는 리소스를 만듭니다.

    useEffect로 전달된 함수는 정리 함수를 반환할 수 있습니다.

    useEffect(() => {
      const subscription = props.source.subscribe();
      return () => {
        // subscribe 정리
        subscription.unsubscribe();
      }
    });

    정리 함수는 메모리 누수 방지를 위해 컴포넌트를 제거하기 전에 수행됩니다. 그리고 여러번 렌더링이 된다면 이전 effect가 정리되고 새로운 effect가 수행됩니다.

     

    effect 타이밍

    useEffect로 전달된 함수는 렌더링이 완료된 후에 실행됩니다. 특정 작업이 렌더링되는 화면을 차단하지 않는 이점이 있습니다.

    하지만 DOM변경과 같은 작업은 렌더링 이전에 실행되어야 합니다. 이를 위해 useLayoutEffect라는 Hook이 있습니다. 수행하는 경우에만 useEffect와 차이가 납니다.

     

    조건부 effect 발생

    effect는 모든 렌더링이 완료된 후에 effect를 발생시키고, 연관된 한 가지가 변경되면 effect가 재생성됩니다. 이 과정이 과도한 작업일 수 있기 때문에 특정 값이 변경될 경우에만 갱신할 수 있습니다. useEffect에 effect에 종속되어 있는 두 번째 인자를 전달하면 됩니다. 예를 보면 props.source가 변경될 때에만 구독이 재생성됩니다.

    useEffect(
      () => {
        const subscription = props.source.subscribe();
        return () => {
          subscription.unsubscribe();
        };
      },
      [props.source],
    );

    만약에 effect를 mount또는 unmount할 때 한 번만 실행하고 싶다면 두 번째 인자로 [] (빈배열)을 전달하면 됩니다. 이는 어떤 값에도 의존하지 않으므로 다시 실행할 필요가 없다는 것을 알려줍니다.

     

     

    useContext

    const value = useContext(MyContext);

     

    context ko.reactjs.org/docs/context.html

     

    Context – React

    A JavaScript library for building user interfaces

    ko.reactjs.org

     


     

    추가 Hook

     

    useReducer

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

    useState의 대체 함수입니다.

    (state, action) => newState의 형태로 reducer를 받고 현재 state를 반환합니다.

    다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우나 다음 state가 이전 state에 의존적인 경우에 사용됩니다.

     

    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:
          throw new Error();
      }
    }
    
    function Counter() {
      const [state, dispatch] = useReducer(reducer, initialState);
      return (
        <>
          Count: {state.count}
          <button onClick={() => dispatch({type: 'decrement'})}>-</button>
          <button onClick={() => dispatch({type: 'increment'})}>+</button>
        </>
      );
    }

     

    초기 state의 구체화

    const [state, dispatch] = useReducer(
      reducer,
      {count: initialCount}
    );

     

    초기화 지연

    초기 state를 지연하여 생성할 수 있습니다. 이를 위해 init 함수를 세번째 인수로 전달합니다.

    function init(initialCount) {
      return {count: initialCount};
    }
    
    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({initialCount}) {
      const [state, dispatch] = useReducer(reducer, initialCount, init);
      return (
        <>
          Count: {state.count}
          <button
            onClick={() => dispatch({type: 'reset', payload: initialCount})}>
            Reset
          </button>
          <button onClick={() => dispatch({type: 'decrement'})}>-</button>
          <button onClick={() => dispatch({type: 'increment'})}>+</button>
        </>
      );
    }
    

     

     

     

     

    댓글

Designed by CHANUL