集成@dnd-kit与react-hook-form useFieldArray时遇即时过渡异常
问题:集成@dnd-kit与react-hook-form useFieldArray组件时的拖拽过渡异常
在集成@dnd-kit与react-hook-form的useFieldArray组件时,遇到异常问题:拖拽元素释放后会出现意外的即时过渡效果。为避免字段被立即更新,我创建了单独的副本用于UI层面处理,但问题仍未解决;即便未对字段或react-hook-form的状态进行任何更新,过渡依然是即时触发的。
相关代码如下:
type FormData = z.infer<typeof formDataSchema> type UseSortableReturn = Omit< ReturnType<typeof useSortable>, 'setNodeRef' | 'transform' | 'transition' > function SortableItem(props: { id: string children: (args: UseSortableReturn) => React.ReactNode }) { const { setNodeRef, transform, transition, ...rest } = useSortable({ id: props.id }) const style = { transform: CSS.Transform.toString(transform), transition } return ( <div ref={setNodeRef} style={style}> {props.children({ ...rest })} </div> ) } export default function App() { const { control, setValue } = useForm<FormData>({ resolver: zodResolver(formDataSchema), defaultValues: { people: new Array(6).fill(1).map((_, index) => ({ fname: (index + 1).toString(), lname: (index + 1).toString() })) } }) const modifiers = [restrictToVerticalAxis, restrictToParentElement] const { fields } = useFieldArray({ control, name: 'people' }) const [items, setItems] = useState([...fields]) useEffect(() => { fields.forEach((item, index) => { setValue(`people.${index}.fname`, items[index].fname) setValue(`people.${index}.lname`, items[index].lname) }) }, [items, fields, setValue]) return ( <form className="w-full h-screen flex items-center justify-center px-8 max-w-screen-md mx-auto w-full"> <div className="grid bg-green-400 p-2 gap-2 rounded"> <DndContext modifiers={modifiers} onDragEnd={(event) => { const { active, over } = event if (over && active.id !== over?.id) { const oldIndex = items.findIndex((item) => item.id === active.id) const newIndex = items.findIndex((item) => item.id === over.id) const nextItems = arrayMove(items, oldIndex, newIndex) setItems(nextItems) console.log(nextItems.map((i) => i.fname)) } }} > <SortableContext items={items}> {items.map((field) => { return ( <React.Fragment key={field.id}> <SortableItem id={field.id}> {({ attributes, listeners }) => ( <div className="bg-green-200 rounded py-2 px-4 flex items-center space-x-4 select-none"> <div className="w-8 h-8 rounded bg-blue-300 -ml-2" {...attributes} {...listeners} /> <div className="font-mono font-semibold text-green-950 flex space-x-4 py-5"> <span>{field.fname}</span> <span>{field.id.toUpperCase()}</span> </div> </div> )} </SortableItem> </React.Fragment> ) })} </SortableContext> </DndContext> </div> </form> ) }
内容的提问来源于stack exchange,提问作者The Truth
相关产品推荐
相关产品推荐

