최신 프런트엔드 프레임워크가 부족한 부분과 이들과 자신을 돕는 방법

13987 단어 spawebdevtypescriptssr
페이지 간에 통신해야 하는 경우 몇 가지 옵션이 있습니다.
  • 프레임워크의 이벤트 기능 사용
  • 글로벌 매장을 갖고 거기에 무언가를 담다
  • 쿼리 문자열을 사용하여 정보를 추가합니다
  • .

    이러한 모든 것에는 단점이 있으며 프레임워크에서 라우팅 및 구성 요소를 처리하는 방식으로 인해 항상 작동하지 않을 수 있습니다. 또한 "경로를 변경하기 전이나 후에 데이터를 변경해야 합니까?"라는 문제도 있습니다. 그리고 "내 구성 요소에서 데이터 변경 사항을 볼 수 있습니까?"
    ContactsCrud 항목의 행을 포함하는 Contact 위젯이 있습니다. 연락처 세부 정보(통화 기록 포함)를 표시하는 구성 요소ContactPage가 있습니다. ContactsCrud에서 연락처의 전화번호를 클릭하면 해당 전화번호ContactPage로 이동하여 새 통화를 시작하는 코드를 실행하고 적절한 UI를 표시합니다.

    그렇게 하는 방법... 구성 요소가 아직 렌더링되지 않아 응답할 수 없기 때문에 이벤트를 할 수 없으며 마운트 시 이벤트를 수신하는 경우 너무 늦을 것입니다. 글로벌 스토어를 사용할 수 있지만 비슷한 것이 필요할 때마다 상용구를 작성해야 합니다. 쿼리 문자열도 마찬가지지만 훨씬 더 복잡합니다.

    내 솔루션? 메시지 전달/명령 디자인 패턴.

    (G)ADTs에 대한 액세스 권한이 없으므로 먼저 메시지 정의로 타이프스크립트를 지원합니다.

    /**
     * Here we define both the messages' names
     * and their data payload. Note that we use
     * `{}` if we don't need data, just so we
     * can use equality comparisons in our implementations
     */
    export interface MessagesPayloadMap {
      StartNewCall: {
        contactId: API.Id;
      };
      Test: {};
    }
    
    /**
     * We can use types that extend from this
     * to get god-tier autocompletion
     */
    export type MessageType = keyof MessagesPaylodMap;
    
    /**
     * Just a shorthand to get the payload for the
     * given message type
     */
    export type MessagePayload<M extends MessageType> = MessagesPayloadMap[M];
    
    /**
     * How our messages actually look like
     */
    export interface Message<M extends MessageType> {
      name: M;
      data: MessagePayload<M>;
    };
    
    /**
     * The type of our enum-style object that contains
     * all the message factories
     */
    export type MessageFactoriesEnum = {
      [M in MessageType]: (payload?: MessagePayload<M>): Message<M>;
    }
    
    /**
     * What we get when querying messages
     */
    export interface MessageQuery<M extends MessageType> {
      message: Message<M>;
    
      /**
       * When querying, calling this function will
       * remove the message from the system
       */
      markAsCompleted: () => void;
    }
    
    /**
     * Type of the callbacks that process messages
     */
    export type MessageProcessor<M extends MessageType> = (message: Message<M>, markAsCompleted: () => void) => void;
    


    이러한 유형 정의를 염두에 두고 다음과 같은 핵심을 얻을 수 있습니다.

    export const Messages: MessageFactoriesEnum = {
      StartNewCall: (data: MessagePayload<"StartNewCall">) => ({
        name: "StartNewCall",
        data,
      })
      Test: () => ({
        name: "Test",
        data: {},
      }),
    };
    
    export interface WorkQueue<M extends MessageType> {
      getQuery(): MessageQuery<M>[];
    
      /**
       * Processor might not be called (if the queue is empty)
       */
      query(messageProcessor: MessageProcessor<M>): void;
    
      /**
       * Processor might not be called (if the queue is empty)
       */
      queryLast(messageProcessor: MessageProcessor<M>): void;
    
      /**
       * Processor might not be called (if the queue is empty)
       */
      queryFirst(messageProcessor: MessageProcessor<M>): void;
    };
    
    export interface MessagePassing {
      emit<M extends MessageType>(messageType: M, payload: MessagePayload<M>): void;
    
      dispatch<M extends MessageType>(message: Message<M>): void;
    
      on<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    
      off<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    
      once<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    
      queryLast<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    
      queryFirst<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    
      query<M extends MessageType>(messageType: M, messageProcessor: MessageProcessor<M>): void;
    }
    


    그리고 이것으로 우리는 통화 두통을 없앨 수 있습니다.
  • 탐색하기 전에 mp.dispatch(Messages.StartNewCall({ contactId: 42 }))에 전화하십시오.
  • ContactPage의 첫 번째 렌더링에서 필요한 하위 구성 요소에서 mp.queryLast(callback)를 호출하십시오.

  • 이 접근 방식의 보너스 포인트는 다음과 같습니다.
  • 메시지를 쿼리하는 인스턴스가 여러 개 있을 수 있습니다(단 하나만 완료로 표시하는 경우)
  • .
  • 메시지 쿼리가 대기열의 실제 메시지와 "독립적"임(즉, 대기열에서 메시지를 삭제해도 쿼리에서 삭제되지 않음)
  • 데이터가 있는 한 어디서나 메시지를 발송할 수 있습니다
  • .
  • 서버에서는 필요하지 않으므로 프레임워크용 클라이언트 전용 플러그인으로 만들 수 있습니다
  • .

    좋은 웹페이지 즐겨찾기