実用的なビット - React カスタム フック

11523 ワード

コンセプトを使って自分の経験を書くシリーズを始めています.私がこれを行っているのは、ほとんどの場合、私たちが使用するツールの新しい概念や特別な概念について耳にするが、それらを使用したり、完全に理解したりすることは決してないからです.主に、使用するツール (HTML、CSS、React) を習得するためにこれを行っているため、免責事項として、これは専門家の意見ではありません.

最近、さまざまなコンポーネント間でロジックをコピー/貼り付けしようとしているときに問題が発生しました.コンポーネントはドロップダウンと入力要素でした.できるようにする必要がありました
  • ドロップダウンの外をクリックするとドロップダウンが閉じ、
  • 入力フィールド以外の場所をクリックすると、入力フィールドが非表示になります

  • ということで、共通点は「要素の外をクリックしたとき」でした.このためのパッケージがあります.最後のセクションのリンクを探してください.また、簡単な解決策を見つけて、ドロップダウン要素で機能させました.ロジックを何度も繰り返すのを避けるために、カスタム フックを使用することを考えました.

    ドロップダウン コンポーネントのスニペット

     const selectRef = useRef(null);
     useEffect(() => {
       function handleClickOutside(event) {
         if (selectRef.current && !selectRef.current.contains(event.target)) {
           close();
         }
       }
       document.addEventListener("mousedown", handleClickOutside);
       return () => {
         document.removeEventListener("mousedown", handleClickOutside);
       };
     }, [selectRef]);
    
     return (<div ref={selectRef}></div>)
    


    基本的に、mousedown イベントをリッスンして handleClickOutside 関数を実行するイベント リスナーを追加します.関数は、クリックされた要素が指定された参照を持つ要素であるかどうかを確認し、そうでない場合は、div のドロップダウンを閉じる関数 close() を呼び出します.

    カスタム フックは、再利用可能なロジックを関数に抽出するのに役立ちます.ロジックをフックに抽出する

    import { useState, useEffect } from "react";
    
    export function useClickedOut(ref) {
    const [active, setActive] = useState(false);
    
     const onClickOutside = (event) => {
       if (ref.current && !ref.current.contains(event.target)) {
         setActive(false);
       }
     };
    
     useEffect(() => {
       document.addEventListener("mousedown", onClickOutside);
       return () => {
         document.removeEventListener("mousedown", onClickOutside);
       };
     });
    
     return [active, setActive];
    };
    


    ここでは、状態 active があり、ユーザーがターゲット ref の外側をクリックすると常に false に設定されます.

    ドロップダウン コンポーネントでフックを使用する

    const Dropdown = () => {
     const targetRef = useRef(null);
     const [ menuOpen, setMenuOpen ] = useClickOutside(targetRef);
    
     const onMenuBtnClick = () => {
       setMenuOpen(!menuOpen);
     };
    
     return (
       <div ref={targetRef} className="dropdown-wrapper">
         <button className="openMenu" type="button" onClick={onMenuBtnClick}>
           Open Dropdown Menu
         </button>
         {menuOpen && (
           <div className="dropdown-items-wrapper">
             <h3>Menu Items</h3>
             <ul className="dropdown-items">
               <li className="dropdown-item">Dropdown Item 1</li>
               <li className="dropdown-item">Dropdown Item 2</li>
               <li className="dropdown-item">Dropdown Item 3</li>
             </ul>
           </div>
         )}
       </div>
     );
    };
    


    これで、ユーザーが特定の要素の外側をクリックした後、アクションが必要な場所ならどこでもこのフックを使用できます.

    全身イラストも載せておきます here

    これを読んで楽しんでいただければ幸いです.あなたの考えや試したこと、またはこれをどのように解決したかについて、お気軽にコメントしてください.

    参考文献と参考文献
    Using a Custom Hook
    Detect click outside React component
    React Click Outside