Closed9

細かなコンポーネントくらいはChatGPT使ったらいい感じにできそう

suusuu

私・・・


ReactでonFocusを実行するとプルダウンが開き、onBlurを受け取るとプルダウンが閉じるコンポーネントを作成したい。
プルダウン内の要素をクリックしてもプルダウンが閉じなようにしたい。
なので、親要素でonBlueを受け取った際にrelatedTargetが親子関係が判定するコードを書いて。
わかりやすく記事にできるようにわかりやすく教えて


suusuu

GPT・・・


了解しました。以下に、Reactでプルダウンが開閉するコンポーネントを作成し、親要素でonBlurを受け取った際にrelatedTargetが親子関係にあるかどうかを判定するコードを示します。

import React, { useRef, useState } from 'react';

function Dropdown() {
  const dropdownRef = useRef(null);
  const [isOpen, setIsOpen] = useState(false);

  const handleToggle = () => {
    setIsOpen(!isOpen);
  };

  const handleBlur = (event) => {
    const relatedTarget = event.relatedTarget;

    if (relatedTarget && dropdownRef.current.contains(relatedTarget)) {
      // 関連するターゲットがプルダウン内の要素なら何もしない
      return;
    }

    setIsOpen(false);
  };

  return (
    <div className="dropdown" onBlur={handleBlur} ref={dropdownRef}>
      <button className="dropdown-toggle" onClick={handleToggle}>
        プルダウン
      </button>
      {isOpen && (
        <div className="dropdown-menu">
          <div className="dropdown-item">アイテム1</div>
          <div className="dropdown-item">アイテム2</div>
          <div className="dropdown-item">アイテム3</div>
        </div>
      )}
    </div>
  );
}

export default Dropdown;

このコードでは、Dropdownコンポーネントがプルダウンを表示するための要素を持っています。プルダウンの表示/非表示の状態はisOpenステートで管理され、handleToggle関数によって切り替えられます。

onBlurイベントは親要素で受け取られ、handleBlur関数が実行されます。この関数では、event.relatedTargetを使用して関連するターゲットを取得し、dropdownRef.current.contains(relatedTarget)を使って親要素内に関連するターゲットが含まれているかどうかを判定します。もし関連するターゲットがプルダウン内の要素である場合は、プルダウンが閉じないようにreturnします。それ以外の場合は、プルダウンを閉じるためにsetIsOpen(false)を呼び出します。

このコンポーネントを使ってプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようになります。Dropdownコンポーネントを使って記事を作成する際に、必要な説明やコードを追加してください。


suusuu

GPT・・・


もちろんです!TypeScriptで上記のコードを書き直しましょう。

import React, { useRef, useState } from 'react';

function Dropdown() {
  const dropdownRef = useRef<HTMLDivElement>(null);
  const [isOpen, setIsOpen] = useState(false);

  const handleToggle = () => {
    setIsOpen(!isOpen);
  };

  const handleBlur = (event: React.FocusEvent<HTMLDivElement>) => {
    const relatedTarget = event.relatedTarget as HTMLElement;

    if (relatedTarget && dropdownRef.current?.contains(relatedTarget)) {
      // 関連するターゲットがプルダウン内の要素なら何もしない
      return;
    }

    setIsOpen(false);
  };

  return (
    <div className="dropdown" onBlur={handleBlur} ref={dropdownRef}>
      <button className="dropdown-toggle" onClick={handleToggle}>
        プルダウン
      </button>
      {isOpen && (
        <div className="dropdown-menu">
          <div className="dropdown-item">アイテム1</div>
          <div className="dropdown-item">アイテム2</div>
          <div className="dropdown-item">アイテム3</div>
        </div>
      )}
    </div>
  );
}

export default Dropdown;

上記のコードでは、useRefフックにHTMLDivElementの型を指定し、dropdownRefを参照しています。また、handleBlur関数にはReact.FocusEvent<HTMLDivElement>の型が指定されています。

さらに、関連するターゲットがプルダウン内の要素であるかどうかをチェックするためにrelatedTargetHTMLElementとしてアサートしています。

TypeScriptの型情報を追加することで、コードの安全性を向上させることができます。useRefフックやイベントハンドラの型指定を行うことで、コンパイル時にエラーを検出することができます。

この修正済みのコードを使用して、TypeScriptでプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようにするコンポーネントを作成できます。


suusuu

GPT・・・


もちろんです!以下に、Vue 3でプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようにするコンポーネントの例を示します。

<template>
  <div class="dropdown" @blur="handleBlur" ref="dropdownRef">
    <button class="dropdown-toggle" @click="handleToggle">
      プルダウン
    </button>
    <div v-if="isOpen" class="dropdown-menu">
      <div class="dropdown-item">アイテム1</div>
      <div class="dropdown-item">アイテム2</div>
      <div class="dropdown-item">アイテム3</div>
    </div>
  </div>
</template>

<script>
import { ref, reactive } from 'vue';

export default {
  setup() {
    const dropdownRef = ref(null);
    const state = reactive({
      isOpen: false
    });

    const handleToggle = () => {
      state.isOpen = !state.isOpen;
    };

    const handleBlur = (event) => {
      const relatedTarget = event.relatedTarget;

      if (relatedTarget && dropdownRef.value?.contains(relatedTarget)) {
        // 関連するターゲットがプルダウン内の要素なら何もしない
        return;
      }

      state.isOpen = false;
    };

    return {
      dropdownRef,
      isOpen: state.isOpen,
      handleToggle,
      handleBlur
    };
  }
};
</script>

上記の例では、refを使用してdropdownRefを参照し、reactiveを使用してstateオブジェクトを作成しています。

handleToggle関数はプルダウンの表示/非表示の状態を切り替えるために使用されます。

handleBlur関数では、relatedTargetを取得し、dropdownRef.value?.contains(relatedTarget)を使用して関連するターゲットがプルダウン内の要素であるかどうかを判定しています。もし関連するターゲットがプルダウン内の要素である場合は、プルダウンが閉じないようにreturnします。それ以外の場合は、state.isOpenfalseに設定してプルダウンを閉じます。

Vue 3のComposition APIを使用してコンポーネントを記述しています。setupメソッド内でデータやメソッドを定義し、returnでそれらをエクスポートしています。

この修正済みのコードを使用して、Vue 3でプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようにするコンポーネントを作成できます。


suusuu

文句も言わず、数秒でVueに作り替える。天才かよ😂

このスクラップは2023/06/25にクローズされました