[React] 당신은 상태를 필요로 하지 않을 것입니다. #5 - 부작용 편
Table of contents
이 포스트는 React 버전 18.3.1을 기준으로 합니다.
잠깐! 동시성 렌더링에 대해 아직 잘 모른다면 [React] 변화의 물결, 동시성 렌더링을 먼저 읽어보세요!
부작용(정리가 필요한)을 가진 상태는 어떻게 해야 할까요? 렌더링과 커밋이 반드시 한 쌍을 이루지는 않으므로 상태를 렌더링 중 생성하고 useEffect
를 통해 정리 함수를 호출하는 것은 적절치 않습니다. React 개발팀은 의도적으로 부작용을 관련 기능을 통해서 처리하도록 하고 있습니다. 따라서 이를 해결하기 위해서는 이에 따라야 합니다.
function <S>(
factory: () => S,
effect: () => () => void,
deps: React.DependencyList
): S {
const state = useDerivedState(factory, deps);
useEffect(effect, deps);
return state;
}
위 코드 중
useDerivedState
는 파생 상태를 보존하기 위해 사용하는 가상의 함수입니다. 자세한 내용은 [React] 당신은 상태를 필요로 하지 않을 것입니다. #2 - 보존(with. useRef) 편에서 확인할 수 있습니다.
위와 같은 코드를 생각할 수 있습니다. 여기서 중요한 점은 factory
에 있던 부작용을 effect
로 옮겨야 한다는 점입니다. 이것을 간단히 행할 수 있다면 좋겠지만 안타깝게도 항상 그런 것은 아닙니다. 이미 구현된 기능을 빌려 사용하는 경우라면 더욱 그럴 것입니다. 예를 들어 생성자에 부작용이 포함된 경우를 생각할 수 있습니다.
제한적인 방향
모든 상황에 적용되는 해결책을 제시할 수는 없지만 아래와 같은 두 가지 방향을 제시할 수는 있습니다.
해당 유형을 감싸는 래퍼를 구현합니다. 이것은 사용 유형을 변경하는 일이기 때문에 달갑지는 않을 수 있습니다. 하지만 가장 간단한 해결책임은 틀림없습니다. 제안은 간단합니다. 생성자를 별도의 초기화 메소드에서 호출하는 방식을 사용합니다. 그 후 필요한 기능을 메소드로 노출해 사용합니다.
해당 유형을 상속하는 유형을 구현합니다. 이것은 첫 번째 내용에 포함될 수 있습니다. 하지만 보다 손이 많이 갈 수 있습니다. 래퍼의 경우, 일부 메소드만 다소 조잡하게 노출하더라도 상관없을 수 있습니다. 하지만 상속을 받으면 그에 맞는 모든 메소드를 노출해야 합니다. 그 대신 같은 유형을 사용할 수 있다는 이점이 있습니다.
위 두 가지 제안 모두 단순하게 구현하는 경우, 어렵지 않습니다. 하지만 실제와 비슷하게 구현할 필요가 있다면 상황은 복잡해질 것입니다. 예를 들어 원본 유형의 생성자를 호출하기 전이라도 일부 기능을 사용할 수 있어야 한다면 어떻게 할까요? 기능을 시뮬레이션하도록 구현해야 할 것입니다. 또는 비동기적 작업이라면 처리를 미루고 원본을 초기화한 뒤 일괄 처리해야 할 수도 있습니다.
읽어주셔서 감사합니다!
주인장의 라이브러리
블로그 주인장이 구현한 라이브러리입니다! 기능을 직접 구현하는 대신 사용할 수 있습니다!
묻고 답하기
개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.
Subscribe to my newsletter
Read articles from 고라니드로 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by