細かなコンポーネントくらいはChatGPT使ったらいい感じにできそう
私とChatGPTとの会話を記録する
私・・・
ReactでonFocusを実行するとプルダウンが開き、onBlurを受け取るとプルダウンが閉じるコンポーネントを作成したい。
プルダウン内の要素をクリックしてもプルダウンが閉じなようにしたい。
なので、親要素でonBlueを受け取った際にrelatedTargetが親子関係が判定するコードを書いて。
わかりやすく記事にできるようにわかりやすく教えて
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
コンポーネントを使って記事を作成する際に、必要な説明やコードを追加してください。
私・・・
typescriptでおねがい
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>
の型が指定されています。
さらに、関連するターゲットがプルダウン内の要素であるかどうかをチェックするためにrelatedTarget
をHTMLElement
としてアサートしています。
TypeScriptの型情報を追加することで、コードの安全性を向上させることができます。useRef
フックやイベントハンドラの型指定を行うことで、コンパイル時にエラーを検出することができます。
この修正済みのコードを使用して、TypeScriptでプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようにするコンポーネントを作成できます。
結論。
ChatGPTは神
欲張ってVue3でも書かせてみた
私・・・
Vue3で書いて
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.isOpen
をfalse
に設定してプルダウンを閉じます。
Vue 3のComposition APIを使用してコンポーネントを記述しています。setup
メソッド内でデータやメソッドを定義し、return
でそれらをエクスポートしています。
この修正済みのコードを使用して、Vue 3でプルダウンが開閉し、プルダウン内の要素をクリックしてもプルダウンが閉じないようにするコンポーネントを作成できます。
文句も言わず、数秒でVueに作り替える。天才かよ😂