[TIL] 2022/03/24

yongkini ·2022년 3월 24일
0

Today I Learned

목록 보기
125/173

Today I Learned

useRef를 사용하면 특정 변수 값을 변경해도 리렌더링이 일어나지 않고(state처럼), 그 변경사항을 바로 조회해도 딜레이가 일어나지 않는다(setState처럼)

이러한 특성을 가진 useRef를 보통 DOM을 참조 및 가져와서 쓰는데에만 사용했었는데, 개수를 센다던지, 회수를 센다던지의 값을 쓸 때 useRef를 이용해서 사용하면 좋을 것 같다. 이를 사용하면 딜레이의 걱정도 없고, 리렌더링이 될 일도 없기 때문이다.

useEffect에서 unmount 함수를 넣어주면 state가 변경되기 직전에 activate된다.

  useEffect(() => {
    console.log("user 값이 설정됨");
    console.log(users);
    return () => {
      console.log("user 가 바뀌기 전..");
      console.log(users);
    };
  }, [users]);

위와 같은 로직을 짰다고 할 때, setUsers를 쓰고, 그에 따라 users가 바뀌기 직전에 return에 넣어준 함수가 activate된다고 생각하면 된다. 물론 본래 언마운트 함수가 그러하듯이 언마운트 될 때도 activate된다.
** 위와 같은 기능이 있기에 만약에 useEffect 내에서 setInterval등을 쓴다면 언마운트 함수로 clearInterval을 해주는 것이 좋다. state가 변경될 때마다 setInterval을 실행한다고 했을 때 새로 실행하기 직전에 이전 interval을 지워줘야하기 때문이다.

React.memo & useCallback & useMemo는 꼭 필요할 때만 쓰자

지난번에도 공부했지만, 최적화툴을 남용하면 안된다. 오히려 역효과가 난다. React.memo 같은 경우도 부모 컴포넌트 리렌더링시에 props를 직접 비교하는 로직을 통해 최적화를 하기 때문에(본래는 부모 컴포넌트가 리렌더링되면 비교 로직 없이 자식 컴포넌트는 무조건 리렌더링) 굳이 최적화 로직이 필요없다면, 비교할 필요가 없다. 따라서 useCallback, React.memo는 반드시 최적화가 필요한 곳에 써야한다. 주로 거의 리렌더링될 일이 없는 컴포넌트 혹은 부모 컴포넌트가 리렌더링 될일이 많지만 자식 컴포넌트는 그렇지 않을 때 자식 컴포넌트에 React.memo를 써주고, 부모 컴포넌트에서 props로 특정한 값을 내려주는 경우에, 그리고 거기에 함수가 있다면 무조건 리렌더링되기에 useCallback을 써준다.

useMemo 는 특정한 객체를 props로 내려주거나, 계속해서 어떤 값을 map or filter 등의 로직을 거쳐 리턴하는 값에 써준다.

예를 들어, 사람들중에 ranked=true인 사람을 계속해서 filtering해서 출력해야하는 부분이 있다고 가정해보자. 이 때,

const People = () => {
  const [people, setPeople] = useState(0);
  const rankedPeople = () => people.filter(el => el.ranked=true); 

  return (
      <div>{rankedPeople}</div>
  )
};

export default People;

위와 같은 컴포넌트가 있을 때, People 컴포넌트는 people state값이 바뀌지 않아도 People 컴포넌트가 리렌더링될 때마다 필터링을 계속해서 진행한다. 하지만 저기를

  const rankedPeople = useMemo(() => people.filter(el => el.ranked=true),[people]);; 

이렇게 바꿔주면 people state가 바뀐 경우에만 필터로직을 실행하여 최적화할 수 있다. 이에 더하여 useMemo는 useCallback을 쓸 때 우리는 함수가 계속해서 새로운 참조값을 갖고 props로 재생성돼 전달되어 리렌더링하는 이슈를 잡고자하는 것처럼

const someObject = useMemo(() => { someObject's values },[]);

위와 같이 해서 props로 내려주면 새로운 값을 참조해서 재생성하지 않고 기존의 값을 기억해서 사용한다. 따라서 무의미한 리렌더링이 발생하지 않도록 해준다.

profile
완벽함 보다는 최선의 결과를 위해 끊임없이 노력하는 개발자

0개의 댓글