我正在创建一个DropDown组件,并将代码从Tailwind UI Simple Selector复制粘贴到名为DropDown.tsx
的文件中
import { Fragment, useState } from 'react'
import { Listbox, Transition } from '@headlessui/react'
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/20/solid'
const people = [
{ id: 1, name: 'Wade Cooper' },
{ id: 2, name: 'Arlene Mccoy' },
{ id: 3, name: 'Devon Webb' },
{ id: 4, name: 'Tom Cook' },
{ id: 5, name: 'Tanya Fox' },
{ id: 6, name: 'Hellen Schmidt' },
{ id: 7, name: 'Caroline Schultz' },
{ id: 8, name: 'Mason Heaney' },
{ id: 9, name: 'Claudie Smitham' },
{ id: 10, name: 'Emil Schaefer' },
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function DropDown() {
const [selected, setSelected] = useState(people[3])
return (
<Listbox value={selected} onChange={setSelected}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700">Assigned to</Listbox.Label>
<div className="relative mt-1">
<Listbox.Button className="relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm">
<span className="block truncate">{selected.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{people.map((person) => (
<Listbox.Option
key={person.id}
className={({ active }) =>
classNames(
active ? 'text-white bg-indigo-600' : 'text-gray-900',
'relative cursor-default select-none py-2 pl-3 pr-9'
)
}
value={person}
>
{({ selected, active }) => (
<>
<span className={classNames(selected ? 'font-semibold' : 'font-normal', 'block truncate')}>
{person.name}
</span>
{selected ? (
<span
className={classNames(
active ? 'text-white' : 'text-indigo-600',
'absolute inset-y-0 right-0 flex items-center pr-4'
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
)
}
然后,我通过import DropDown from "./DropDown";
将该组件导入到我的App.tsx
中,并使用<DropDown />
进行渲染
所有工程罚款和渲染。
但是我可以做我想做的事情,我不会把DropDown.tsx
中的selected
的值转换成App.tsx
。
我尝试了几种方法向下拉列表添加属性,或者使用onChange
或onClick
。也许我需要在组件上发出一个事件?
我希望App.tsx
中的onChange
调用一个值为selected
的函数。
const handleSelectChange = async (exampleChange: any) => {
const value = exampleChange;
console.log("adad")
// set the current example to the selected one
setExample(value)
// retrieve the example data and update the inputs and code
const example_code = await getExample(value)
setInputs(await example_code[0])
setCode(await example_code[1])
// reset the output
setOutput(emptyOutput)
}
非常感谢,很抱歉这么长的帖子
1条答案
按热度按时间wwwo4jvm1#
您可以将回调属性传递给Dropdown组件,该组件将在列表框的onChange事件上调用。
然后,您可以将handleSelectChange函数从应用程序传递到下拉列表中
虽然这样做是可行的,但您也可以考虑将useState钩子移到App中,只将state和state setter传递到Dropdown中,这是React中的常见做法,通常称为“提升状态”。