728x90

1. LifeCycle

class 기반 react를 오랫동안 써왔다.

그동안은 LifeCycle이 굉장히 중요시 여겨지며

LifeCycle을 기반으로 적재 적소에 함수들을 호출해 개발했다.

 

Hooks로 기반을 변경한 뒤,

useEffect에 의존한 단조로운 LifeCycle위에서 개발하게 되었다.

 

그런데, 이 useEffect에서 호출되는 함수들은

어느 시점에 호출되는걸까?

 

useEffect : render -> useEffect -> (re-rendering)

 

DOM의 레이아웃 배치와 페인팅이 끝난 후,

useEffect의 사이트 이펙트에 해당하는 함수들이 호출된다.

 

여기서 아래와 같은 문제가 발생할 수 있다.

1) 사용자가 짧게나마 빈 페이지를 보게됨

2) 기본 값으로 구성된 페이지를 보게됨

 

대부분의 웹 페이지들이

페이지가 열릴때

데이터를 비동기적으로 불러와

state의 갱신을 동해 화면을 re-rendering해서

사용자에게 제공된다는 것을 생각하면

useEffect를 이런식으로 활용하는것에는

어느정도 문제가 있다고 볼수있겠다.

 

그러면 어떻게 하면 좋을까

하고 알아보니

useLayoutEffect라는 것이 있었다.

 

useLayoutEffect : useLayoutEffect -> render -> (useEffect) -> (re-rendering)

 

useEffect와 달리

DOM이 레이아웃 배치 및 페인팅을 하기 전에

즉, render 보다도 먼저 호출된다.

 

useLayoutEffect를 통해

완벽하게 위의 1), 2) 문제를 제어할수는 없어도

좀더 효과적으로 서비스를 제공할수는 있겠다.

 

(위 문제를 완벽하게 해결하려면 SSR방식의 next를 써야할듯하다.)

 

 

 

2. useState

useState는 단연코 가장 많이 쓰이는 hooks일것이다.

프로젝트를 진행하다보니

코드를 올바르게 작성한듯한데

state가 제때 갱신되지 않아서 의도와 다르게

결과값이 나오는 경우가 심심치않게 보였다.

 

이는 동일블록 내에서 setter를 사용할 때

Closer 구조로 인해 발생하는 문제로,

class기반의 react를 사용할때도 가지고 있던 문제다.

 

class기반에서도 

setState(prevState => ({ ...prevState, type: value }));

위와 같이 처리하곤 했었는데

hooks에서도 마찬가지로 위와 같은 방식으로

해당 문제를 해결할 수 있다.

 

예를 들어,

const [list, setList] = useState([]);


const updateList = (data) => {
  // setList(list.concat(data)); <-- X
  
  setList(prevList => {
    const newList = list.concat(data);
    return newList;
  });
}

이런식으로 처리하면 된다.

728x90
반응형