섬 전체에 갈고리 상태를 반영하는 방법 🏝

"Island" architecture은 여러 진입점으로 구성된 프런트엔드를 설명하는 비교적 최근에 만들어진 용어입니다. 이는 거대한 구성 요소 트리를 렌더링하는 기존 접근 방식에 도전하여 정적 콘텐츠에서 동적 수화 가능한 요소를 보다 명확하게 격리할 수 있습니다. 그리고 그것은 Fresh , 내가 현재 프로젝트(출시 예정)에 사용하고 있는 Deno 의 새로운 프레임워크로 구워졌습니다!

그러나 이러한 격리에는 공유 상태와 같은 규칙적인 패턴을 금지하는 제한 사항이 있습니다. 이 연습에서는 여러 아일랜드 간에 후크 상태를 동기화하고 애플리케이션의 논리를 체계적으로 유지하는 방법을 다룰 것입니다.

문제의 훅☀️/🌙



내 프로젝트에서 어두운 모드 기본 설정을 활성화하기 위해 "prefers-color-scheme: dark"와 인터페이스에 이 간단한 후크를 추가하고 dark 요소에 body 클래스를 추가하고 기본 설정 재정의를 유지하도록 localstorage에 설정했습니다.

export function useDarkMode() {
    const [dark, setDark] = useState(false);

    function toggleDarkMode() {
      const prefersDark = document.body.classList.toggle('dark');
      setDark(prefersDark);
      localStorage.setItem('prefers-dark', prefersDark);
    }

    useEffect(() => {
      const prefersDark = localStorage.getItem('prefers-dark') === 'true';
      const devicePrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

      if ((prefersDark === null || prefersDark) && devicePrefersDark) {
        toggleDarkMode();
      }
    }, []);

    return [dark, toggleDarkMode];
}


이것은 트리거하는 버튼이 있는 렌더 트리에 대해 작동하지만toggleDarkMode, 아일랜드 접근 방식으로 인해 이 렌더 트리(및 내부 상태)는 다른 트리와 완전히 격리됩니다. 진입점에 관계없이 모든 요소가 올바른dark 상태에 있도록 하려면 섬 사이에 생명선이 있어야 합니다.

입력: 이벤트 발송 🛟



이 문제( MutationObserver 등)를 해결하기 위한 많은 접근 방식이 있지만 가장 간단한 방법은 이 후크의 다른 인스턴스가 수신 대기할 수 있는 이벤트를 전달하는 것입니다.

이 경우 각 아일랜드가 toggleDarkMode 함수를 호출하도록 트리거하고 (적절한 조건으로) 해당 상태를 후크의 트리거 인스턴스와 동기화 상태로 유지합니다. 이를 달성하기 위해 위의 후크에 필요한 수정 사항은 다음과 같습니다.

export function useDarkMode() {
    function toggleDarkMode() {
        // same code as above
        window.dispatchEvent(new Event('dark-mode-preference-updated'));
    }

    function respondToEvent() {
        const prefersDark = document.body.classList.contains('dark');
        setDark(prefersDark);
    }

    useEffect(() => {
        const prefersDark = localStorage.getItem('prefers-dark') === 'true';
        const devicePrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

        if ((prefersDark === null || prefersDark) && devicePrefersDark) {
            if (!document.body.classList.contains('dark')) {
                toggleDarkMode();
            } else if (!dark) {
                setDark(true);
            }
        }

        window.addEventListener('dark-mode-preference-updated', respondToEvent);

        return () => {
            window.removeEventListener('dark-mode-preference-updated');
        };
    }, []);
}


요약하면 각 후크 인스턴스는 마운트 시 사용자의 색 구성표 기본 설정을 확인하고 동일한 함수를 호출하여 해당 값을 상태로 설정합니다.

그런 다음 toggleDarkMode에 대한 모든 호출은 수신할 후크의 다른 모든 인스턴스에 대해 이벤트를 발생시켜 각각이 body의 값을 확인하고 변경을 수행하지 않고 상태에 저장하게 합니다.
localstorage 값은 트리거링 후크에 의해서만 설정되므로 후속 페이지 로드는 올바른 기본 설정 값을 얻습니다.


이는 후크가 공유 상태와 관련하여 단순화하는 것을 목표로 하는 일부와 모순될 수 있지만 구성 요소 간에 공유되는 논리가 단일 위치에 있을 수 있습니다. 이 후크의 구현은 document.body.classList가 진실의 소스가 됨으로써 단순화되지만 더 복잡한 이벤트를 사용하여 인스턴스 간에 데이터를 동기화할 수 있습니다. 어쨌든, 당신의 생각을 알려주고 다른 진입점에서 상태를 미러링하기 위한 다른 제안이 있으면 알려주세요!

좋은 웹페이지 즐겨찾기