1) useEffect

사용하는 방법은 정말 간단한데 의존성 배열에 어떠한 값들을 넣어줘야 하는지를 정확히 판단하기가 어려움이 있어서 정리를 해보려고 한다.

1.1) 의존성 배열

의존성 배열을 꼭 사용해야하는 건 아니지만 필요할 때 사용하게 되는데 의존성 배열을 잘못 관리하게 되면서 뜻하지 않는 오류들을 만날 수 있었다. (무한 렌더링🥲)

💡 가능하다면 의존성 배열을 입력하지 않는 것이 좋다! 꼭 필요한 경우에만 사용하도록 하자!

function Profile({userId}) {
   const [user, setuser] = useState();
   useEffect(() => {
      fetchUser(userId).then(data => setUser(data));
   }, [userId])
}

위의 코드에서 부수효과함수는 Profile 컴포넌트가 렌더링이 될 때마다 서버에 user의 정보를 호출하기 때문에 의존성 배열[] 을 입력하면 마운트 된 이후에 한 번만 호출하도록 할 수 있습니다.
하지만 이럴때의 문제점은 마운트 된 이후 한 번만 호출이 되므로 새로운 사용자 정보를 가져오지 못합니다.
의존성 배열에 userId 값을 입력해주면 새로운 사용자의 새로운 id값이 들어왔을 때 부수효과함수가 실행이 됩니다.

💡 부수효과 함수안에서 사용된 상태값이나 속성값 그리고 그걸 이용해 계산된 어떤 값이 있을 때에 그것을 부수효과함수 안에서 사용했다면 의존성 배열에 넣어줘야한다.

1.2) useEffect를 커스텀 훅으로

만약 useEffect부수효과함수가 바뀌지 않는다거나 한 번만 실행된다고 했을 때에는 [] 빈 배열을 입력하는 것 보다 hook을 따로 만들어 명시적으로 사용해주는 것이 더 좋다.

// Hook
import { useEffect } from 'react';

export default function useOnMounted(effect) {
   useEffect(effect, []);
}
// component
import useOnMounted from ''

function Profile({userId}) {
  const [user, setuser] = useState();
  useOnMounted(() => fetchUser(userId).then(data => setUser(data)))
}

1.3) 부수효과함수 와 async/await

부수효과 함수의 return 값은 무조건 함수타입이어야만 한다.
async/await프로미스 객체이기 때문에 부수효과 함수가 될 수 없다.

만약 부수효과 함수안에서 async/await을 사용하려면 따로 함수를 선언해서 호출하는 방식으로 사용해야한다.

1.4) 부수효과함수에서 의존성 배열로 관리 안하는 법

웬만하면 부수효과 함수에서 의존성 배열을 사용하지 않는 것이 좋다.
왜냐하면 어떠한 속성 값으로 전달되는 함수를 의존성 배열에 추가하는 순간 useCallback 등을 사용해 자주 변경이 되지 않도록 신경써서 관리를 해줘야하기 때문입니다.

부수효과함수 내에서 조건문을 활용하여 실행시점을 조절할 수 있다.

이전 상태값을 기반으로 다음 상태값을 계산할 때 의존성 배열에 해당하는 값을 입력을 하는게 아닌

setCount(prevValue => prevValue + 1))

와 같이 사용 할 수 있다.

useReducer를 사용해 dispatch가 변하지 않는 것을 이용하면 된다.

function Timer( { initialTotalSeconds } ) {
   const [state, dispatch] = useReducer(reducer, {
      hour  : Math.floor(initialtotalSeconds / 3600),
      minute: Math.fllor(( initialTotalSeconds % 3600 ) / 60),
      second: initialTotalSeconds & 60,
   });
   const { hour, minute, second } = state;

   useEffect(() => {
      const id = setInterval(dispatch, 1000);
      return () => clearInterval(id);
   });
}

useRef hook 사용

function MyComponent({ onClick }) {
  useEffect(() => {
    window.addEventListener('click', () => {
      onClick();
      ...
  	}
  }
}

속성 값으로 전달되는 함수는 자주 변경되는 경우가 많다
이와 같은 함수는 내용은 그대로인데 렌더링할 때마다 변경되는 경우가 많다. 그로 인해 부수효과 함수가 부득이하게 자주 호출될 수도 있는 상황이 있다.

function MyComponent( { onClick } ) {
   const onClickRef = useRef();
   useEffect(() => {
      onClickRef.current = onClick;
   })
   useEffect(() => {
      window.addEventListener('click', () => {
         onClickRef.current();
         // ...
      }
   }
}

렌더링이 될 때마다 ref 객체에 onClick 함수를 할당해주고 원래 사용하려던 곳에서 ref객체를 이용해서 함수를 호출하는 방법이 있습니다.
ref 객체는 의존성 배열에 입력하지 않아도 됩니다.


참고
실전 리액트 프로그래밍

0개의 댓글