[21/06/18]今日の開発


田植えをする

ModalWrapperコンポーネントを作成して、次のモードを実現する予定です.



  • アイデア:Modalrapperは、ラップ要素、すなわちサスペンション要素の役割のみを実行します.
  • function Modal({ children, setIsModalShow }) {
      const modalRef = useRef();
      const onClickModal = (e) => {
        if (modalRef.current.className === e.target.className) {
          // 모달 콘텐츠가아닌 모달 바깥누르는 경우
          setIsModalShow(false);
        }
      };
      return (
        <Wrapper ref={modalRef} onClick={onClickModal}>
          {children}
        </Wrapper>
      );
    }

  • 月の歯の外を押すと、月の歯が見えなくなります.onClickModal
  • childrenタグはmodalrapperによって囲まれたサブアセンブリである
  • 以下はModalRapperの最上位コンポーネントです.
    const Wrapper = styled.div`
      height: 100%;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
    
      background-color: rgba(0, 0, 0, 0.5);
    `;
    positionfixed、top:0/left:0に設定してモードを実現する.

    UserDetectOutsideClick Hook


    次のコードを分析します.
    const useDetectOutsideClick: any = (el: React.RefObject<HTMLDivElement>, initialState: boolean) => {
      const [isActive, setIsActive] = useState(initialState);
      useEffect(() => {
        const pageClickEvent = (e: Event) => {
          if (el.current && !el.current.contains(e.target as Node)) {
            setIsActive(!isActive);
          }
        };
    
        if (isActive) {
          window.addEventListener('click', pageClickEvent);
        }
    
        return () => {
          window.removeEventListener('click', pageClickEvent);
        };
      }, [isActive, el]);
    
      return [isActive, setIsActive];
    };
    
  • パラメータ:el(div ref object)、initialState(isModalshow propertyの初期値)
  • まずisModalShowモデルを作成し,展示されたstateモデルを制御する.
    
      const [isActive, setIsActive] = useState(initialState);
    
    次に、pageClickEvent Risner関数を作成します.
    const pageClickEvent = (e: Event) => {
          if (el.current && !el.current.contains(e.target as Node)) {
            // ref 객체의 current, 즉 ref에 값이 잡히는 경우 (렌더 메서드 안에서 ref가 엘리먼트에게 전달되었을 때)
            
            // ref 객체의 current요소가 e.target(클릭한 요소)를 포함하고 있지 않다면, 모달 내부의 컴포넌트가 아닌 외부를 클릭한 경우
            
            // setIsActive(!isActive) isActive를 반대로 
            setIsActive(!isActive);
          }
    };
    renderメソッドでは、refが「レイヤ」に渡されると、ノードへの参照がrefの現在の「レイヤ」ビューに含まれます.
    こうやってイベントレンタルをしたら.
    モードがオンの場合、このイベントリスナーを追加し、モード構成部品が消えた場合、イベントを削除します.(これをしないと活動が累積して付きます)
     useEffect(() => {
        const pageClickEvent = (e: Event) => {
          if (el.current && !el.current.contains(e.target as Node)) {
            setIsActive(!isActive);
          }
        };
    
        if (isActive) {
          window.addEventListener('click', pageClickEvent);
        }
    
        return () => {
          window.removeEventListener('click', pageClickEvent);
        };
      }, [isActive, el]);
    isActiveは、フックを使用する要素から受信され、モードを制御するために使用される.

    useEffect vs useLayoutEffect


    ほとんどの効果は同期して実行する必要はありません.レイアウト内の測定など、一般的ではありませんが、同期して実行する必要がある場合は、userEffectと同じAPIを使用する個別のhookがあります.
  • useEffect
  • 反応整理効果の正確な時間はいつですか?素子がアンインストールされると、反応器は「クリーンアップ」(clean-up)を実行します.
    Effectでは、関連しない論理を分離できます.論理が関連していない場合は、それを別のUserEffectに分離します.
    依存配列を[]のままにしておくと、最初のレンダリング直後に実行されます.
    コンポーネントが最初に表示された場合にのみ、userEffectに登録されている関数が呼び出されます.

    Reference

  • ばか
  • react docs