[React] 당신은 상태를 필요로 하지 않을 것입니다. #5 - 부작용 편

고라니드로고라니드로
2 min read

이 포스트는 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로 옮겨야 한다는 점입니다. 이것을 간단히 행할 수 있다면 좋겠지만 안타깝게도 항상 그런 것은 아닙니다. 이미 구현된 기능을 빌려 사용하는 경우라면 더욱 그럴 것입니다. 예를 들어 생성자에 부작용이 포함된 경우를 생각할 수 있습니다.

제한적인 방향

모든 상황에 적용되는 해결책을 제시할 수는 없지만 아래와 같은 두 가지 방향을 제시할 수는 있습니다.

  1. 해당 유형을 감싸는 래퍼를 구현합니다. 이것은 사용 유형을 변경하는 일이기 때문에 달갑지는 않을 수 있습니다. 하지만 가장 간단한 해결책임은 틀림없습니다. 제안은 간단합니다. 생성자를 별도의 초기화 메소드에서 호출하는 방식을 사용합니다. 그 후 필요한 기능을 메소드로 노출해 사용합니다.

  2. 해당 유형을 상속하는 유형을 구현합니다. 이것은 첫 번째 내용에 포함될 수 있습니다. 하지만 보다 손이 많이 갈 수 있습니다. 래퍼의 경우, 일부 메소드만 다소 조잡하게 노출하더라도 상관없을 수 있습니다. 하지만 상속을 받으면 그에 맞는 모든 메소드를 노출해야 합니다. 그 대신 같은 유형을 사용할 수 있다는 이점이 있습니다.

위 두 가지 제안 모두 단순하게 구현하는 경우, 어렵지 않습니다. 하지만 실제와 비슷하게 구현할 필요가 있다면 상황은 복잡해질 것입니다. 예를 들어 원본 유형의 생성자를 호출하기 전이라도 일부 기능을 사용할 수 있어야 한다면 어떻게 할까요? 기능을 시뮬레이션하도록 구현해야 할 것입니다. 또는 비동기적 작업이라면 처리를 미루고 원본을 초기화한 뒤 일괄 처리해야 할 수도 있습니다.

읽어주셔서 감사합니다!

주인장의 라이브러리

블로그 주인장이 구현한 라이브러리입니다! 기능을 직접 구현하는 대신 사용할 수 있습니다!

묻고 답하기

개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.

0
Subscribe to my newsletter

Read articles from 고라니드로 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

고라니드로
고라니드로