React

React 완벽가이드 useEffect는 어떻게 최신상태를 읽을까?

노엠디엔 2023. 9. 21. 23:10

https://zoon-bloom.tistory.com/129

 

리액트 useEffect 완벽가이드 props와 state

리액트의 함수형 컴포넌트를 사용 시에 꼭 사용하게 되는 useEffect에 대해서 글을 읽다 정리한 내용이 없어 천천히 다시 공부하며 정리할려고 한다. useEffect의 대해서는에 화면에 렌더링이 완료된

zoon-bloom.tistory.com

저번에  useEffect완벽가이드의  상태값은 변경될 때마다
각각의 랜더링에서 함수 안의 있는 고유한 값(상수)이며 컴포넌트는그 값을 볼 뿐이라고 하였다.

 

그럼 useEffect 훅 안에서는 어떻게 state의 최신 상태를 알 수 있을까?

  useEffect(() => {    document.title = `You clicked ${count} times`;  });

이벤트 핸들러는 그 랜더링에 속한 상태를 보게되는데  그 상태는 특정 범위 안에 속하는 변수이기 때문이며
이펙트에도 똑같은 개념이 적용된다고 한다.
useEffect 내에서 동작하는 함수 또한 렌더링마다 고유한 함수이며 그 이펙트는 또 그 렌더링상태의 고유한 state와 props를 보게 되는 것!

 

이펙트는 렌더링 결과의 일부?

이펙트는 렌더링 결과의 일부가 아니라고 함!  그이유는 다음과 같다.

결국 부수효과를 위해 사용되며 비동기적으로 실행되기 때문에 렌더링에는 영향을 끼치지 않아야 하므로?

 

모든 랜더링은 고유한 모든 것을 가지고 있다.

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {    setTimeout(() => {      console.log(`You clicked ${count} times`);    }, 3000);  });  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

해당 코드를 통해 만약에 연속적으로 클릭하거나 뜸을 들여서 클릭하게 되면
어떻게 되는지 블로그에서는 질문을 했었다.

나는 당연하게 앞에 했던 말들이 사실이라면 몇 번을 누르던 누른 만큼 순선대로 나올것 같았다.

다행히 순서대로 누른만큼 출력된다고 함!

 

그런데 클래스 컴포넌트에서는 그렇지 않다고 한다?

componentDidUpdate() {
  setTimeout(() => {
     console.log(`You clicked ${this.state.count} times`);
  }, 3000);
}

이렇게 작성하게 되면 여기서 this  특정 랜더링 시점의 값이 아니라 언제나 최신의 값을 가리키게 되며.
항상 최신의 상태를 가져오게 된다.
 

블로그에서는 훅에서는 자바스크립트의 클로저의 많이 의존하다는 떡밥을? 흘려주는데 

클로저란? https://poiemaweb.com/js-closure

사실 이 클래스문법의 근본적인 문제는 클로저 자체가 문제가 아닌 가변값 변경(mutation)이기 때문이다.

(뭔가 부족하여 chat gpt에 물어보았다)
리액트(React)에서 가변값(mutations) 변경은 컴포넌트의 상태(state)를 직접 수정하는 것을 의미합니다.
리액트는 상태(state) 변경을 추적하고 렌더링을 관리하기 위해 가변값 변경을 권장하지 않습니다.

this가 직접 state 값을 직접 변경기 때문인 것 같다.

 

그래서 이문제는 클로저로 해결이 가능하다고 한다. https://codesandbox.io/s/w7 vjo07055

 

w7vjo07055 - CodeSandbox

w7vjo07055 by gaearon using react, react-dom, react-scripts

codesandbox.io

 

 마지막으로 블로그에서는  “컴포넌트의 랜더링 안에 있는 모든 함수는 (이벤트 핸들러, 이펙트, 타임아웃이나 그 안에서
호출되는 API 등) 랜더(render)가 호출될 때 정의된 props와 state 값을 잡아둔다.” 이 부분에 대해 한번 더 중요시했는데

만약 과거의 랜더링 시점에서 미래의 props나 state를 조회할 필요가 있을 때 
ref를 사용하여 값을 흐름을 제어할 수 있는데 이때는 주의를 해야 한다고 경고하였다.(흐름을 거슬리는 방식?)

나 또한 ref에 사용은 지양해야 한다고 생각하는데 결국 렌더링의 흐름?을 무시하는 것이며 나중에 ref와 관련하여 문제가

생겨 디버깅 시에 정확한 문제의 원인을 찾기 어려울 것 같다. 

그래서 ref를 사용하지 않고 캐러셀 구현 등의  방법들을 찾아보기도 했었지만 실패했다..ㅠ

아마 리액트의 높은 이해도 와 노력이? 필요한 것 같다..

 

'React' 카테고리의 다른 글

SOLID 하게 만들기  (0) 2023.12.21
useEffect완벽 가이드 클린 업  (0) 2023.09.24
리액트 useEffect 완벽가이드 props와 state  (0) 2023.09.21
useEffect 내에서 async await  (0) 2023.09.07
리액트 Ref 와 DOM  (0) 2023.08.31