React를 사용하여 창 관리자 만들기

React 컨텍스트를 사용하여 창 관리자를 작성하는 방법

TL;박사 01 명


  • Source code
  • Online demo
  • 소개하다.


    한동안 JavaScript로 창 관리자가 있는 데스크톱을 만들어 보려고 했습니다.
    나는 마침내 이 기회를 이용하여 웹 응용 프로그램이 되지 말아야 할 스크립트에 전단을 추가했다.
    백엔드는 본고에서 중요하지 않지만 본 예에서 Express API로 복고 게임에 대한 데이터를 제공한다.
    나는 대량의 직접 의존 관계가 있는 프로젝트를 만들고 싶지 않다.나는 그것을 테스트하기 위해 MUI만 추가했다(보조 항목은 새로운 도구를 테스트하는 완벽한 목적이다)🤤).

    특징.


    데스크톱 아이콘


    바탕 화면 아이콘을 이동하여 항상 창 아래에 둡니다.
    아이콘을 두 번 클릭하면 창이 열려 내용을 표시하거나 열린 창의 맨 위로 이동합니다.

    창 구성 요소


    창 구성 요소는 에뮬레이션된 운영 체제 창 관리자의 모든 일반적인 기능을 제공합니다.
  • 수확대
  • 로 드래그 가능
  • 반응 프레임에서 마우스로 크기 조절
  • 제목
  • 을 두 번 클릭하여 크기 조정 가능
  • 제목
  • 의 전용 버튼을 통해 크기 조정 가능
  • 브라우저 창 크기 조정 가능
  • 바닥글
  • 에 일부 정보 표시
  • 롤오버 아이콘
  • 에 따라 바닥글 업데이트
  • 탭 키를 사용하여 초점 맞추기
  • 수확대
  • 의 전용 단추를 통해 닫기
  • Escape로 닫기 가능
  • 파일/게임 아이콘 포함
  • Ctrl+F 또는 Command+F를 사용하여 검색 기능 제공
  • 창 아이콘


    데스크톱 아이콘과 같이 윈도우즈 아이콘은 게임 창을 열 수 있습니다.

    기술 선택


    국가 관리


    Redux와 같은 상태 관리자를 사용하고 싶지 않습니다. 창 창고를 관리하려면 React context 을 사용하십시오.
    나는 이것이 창의 z 인덱스와 상호작용 (icons=>window) 을 처리하는 간단한 방법이 될 것이라고 생각한다.
    상하문은 '전역' 속성을 제공할 수 있지만, 그것들도 상태 처리 프로그램을 제공할 수 있다. 이것이 바로 내가 시도하고자 하는 방법이다.

    창 설명자


    창마다 유일한id, 일부 속성과 유일한...전용 창 상하문
    descriptor.interface.ts
    interface IDescriptor {
      id: string;
      zIndex: number;
      payload: WinPayload;
      options: {
       ...
      };
      state: {
        ...
      }
    }
    
    🤔 윈도우 컨텍스트를 사용하여 상태가 아닌 값을 관리하는 이유는 무엇입니까?
    🤡 왜냐하면 저는 상하문을 이용하고 싶어요.
    😎 이것은 매우 멋진 방법이기 때문에 아이콘 행위와 창/창 관리자 사이에서 도구를 뚫는 것을 피할 수 있다.
    예:
  • 롤오버 시 아이콘이 창 바닥글
  • 을 업데이트합니다.
  • 전역 검색 활성화 활성 창
  • 에서 검색
    기본적으로 창 관리자 트리는 다음과 같습니다.
    <WinManagerContext.Provider value={mainContext}>
      {
        descriptors.map(descriptor => (
          <WinContext.Provider key={descriptor.id} value={winContext}>
            { render(descriptor.payload) }
          </WinContext.Provider>
        )
      }
    </WinManagerContext.Provider>
    
    이것은 이 나무에 대한 간략한 묘사입니다. 왜냐하면 당신이 상상한 바와 같이 다른 몇 가지 문제를 고려해야 하기 때문입니다.
    👉 데스크톱에서 사용할 수 있는 아이콘은 관리자와 상호작용을 하고 제공된 상하문에 끼워 넣어야 합니다.
    👉 여러 종류의 창은 서로 다른 유효 부하 유형으로 표시되며, 창 관리자가 필요로 하는 전용 렌더링 기능으로 렌더링됩니다.

    부호화


    React 컨텍스트 및 사용


    물론, 나는 여기에서 모든 코드를 설명하지 않지만, 상하문을 어떻게 사용하고 갱신하는지 설명할 것이다. 이것은 간단한 특성 덕분이다.

    창 z 인덱스 업데이트



    첫 번째 계획(또는 Tab)을 클릭할 때 첫 번째 계획에 Megadrive 창을 설정하는 것이 목표입니다.
    코드에서, 이것은 설명자의 z 인덱스를 설명자 창고의 최고 값으로 설정합니다.
    창 관리자는 모든 창의 상하문에 처리 프로그램을 제공하여 자신을 주목할 것입니다.
    WinManager.tsx
    const WinManager: FC<Props> = ({ render, children }) => {
      const [descriptors, setDescriptors] = useState<IDescriptor[]>([]);
    
      const focus = (id: string) => {
        setDescriptors(descriptors => {
          const focused = descriptors.reduce((selected, descriptor) => selected.zIndex > descriptor.zIndex ? selected : descriptor);
          return id === focused.id ? descriptors : descriptors.map(descriptor => descriptor.id === id ? {...descriptor, zIndex: focused.zIndex + 1} : descriptor);
        });
      }
    
      return (
        <WinManagerContext.Provider value={mainContext}>
        {
          descriptors.map(descriptor => (
            <WinContext.Provider key={descriptor.id} value={{ focus: focus.bind(null, descriptor.id) }}>
              { render(descriptor.payload) }
            </WinContext.Provider>
          )
        }
        </WinManagerContext.Provider>
      );
    
    };
    
    창에서 유일하게 해야 할 일은 이 프로세서를 사용하는 것입니다.
    Win.tsx
    const Win = () => {
      const { focus } = useContext(WinContext);
      return (
        <div onPointerDown={focus}>
         ...
        </div>
      );
    }
    
    🤟 한 마디로 하면 창의 구성 요소 트리 중 어느 곳에서 창 관리자 상태를 업데이트할 수 있으며, 도구 탐색, 사용자 정의 이벤트, 기타 통신 과정을 처리할 필요가 없습니다.

    프롬프트


    🤓 읽는 데 편리하도록, 이 코드 세션들은 이미 정리되었다.실제 코드에서 대부분의 함수는 성능 목적을 위해 기억된다(useCallback & UseMoom).
    이것이 바로 setDescriptor 함수가 항상 함수와 함께 매개 변수로 사용되는 이유입니다. (의존항에 설명자를 사용할 필요가 없습니다.) 이것은 렌더링을 촉발하기 위해 결과가 정말로 바뀌었는지 확인하는 이유입니다. (같은 그룹 내용 검사)

    결론


    Contextes는 테마나 사용자 데이터만 제공하는 것보다 훨씬 강력합니다.모든 공구와 마찬가지로, 그것은 만능이 아니며, 유용할 때 그것을 사용한다.🙃
    만약 당신에게 어떤 의견이나 문제가 있으면 언제든지 질문하세요!

    좋은 웹페이지 즐겨찾기