shadcn 中反应表单的状态在第二次上传后重置

问题描述 投票:0回答:1

这是我的表单字段,我将图像传递给 imageupload 以在上传到数据库之前预览它们。如果我上传一张图像,一切正常,但如果我上传两张图像,它会覆盖数组而不是添加它。

<FormField
      control={form.control}
            name="images"
            render={({ field }) => {
              return (
                <FormItem>
                  <FormLabel>Images</FormLabel>
                  <FormControl>
                    <ImageUpload
                      value={field.value.map((image) => image.url)}
                      disabled={loading}
                      onChange={(url) => field.onChange([...field.value, { url }])} // Call handleImageChange on image addition
                      onRemove={(url) => field.onChange([...field.value.filter((current) => current.url !== url)])} // Call handleImageRemove on image removal
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )
            }}
          />

这里是上传小部件,这里使用下一个cloudinary。

'use client'

import { useEffect, useState } from 'react'
import { Button } from './button'
import { ImagePlus, Trash } from 'lucide-react'
import Image from 'next/image'

import { CldUploadWidget, CloudinaryUploadWidgetResults } from 'next-cloudinary'

interface ImageUploadProps {
  disabled?: boolean
  onChange: (value: string) => void
  onRemove: (value: string) => void
  value: string[]
}

function ImageUpload({ disabled, onChange, onRemove, value }: ImageUploadProps) {
  const [isMounted, setIsMounted] = useState(false)

  useEffect(() => {
     setIsMounted(true)
   }, [])

  console.log('value:', value)

  const onUpload = (result: CloudinaryUploadWidgetResults) => {
    const info = result.info as object

    console.log('start')
    console.log(value)

    if ('secure_url' in info) {
      const url = info.secure_url as string
      console.log('Uploaded URL:', url)
      onChange(url)
    }
  }

  if (!isMounted) return null

  return (
    <div>
      <div className="mb-4 flex items-center gap-4">
        {value.map((url) => (
          <div key={url} className="relative h-[200px] w-[200px] overflow-hidden rounded-md">
            <div className="absolute right-2 top-2 z-10">
              <Button type="button" onClick={() => onRemove(url)} variant="destructive" size="icon">
                <Trash className="h-4 w-4" />
              </Button>
            </div>
            <Image fill className="object-cover" alt="image" src={url} />
          </div>
        ))}
      </div>
      <CldUploadWidget onSuccess={onUpload} uploadPreset="erx1yvtk">
        {({ open }) => {
          const onClick = () => {
            open()
          }
          return (
            <Button type="button" disabled={disabled} variant="secondary" onClick={onClick}>
              <ImagePlus className="mr-2 h-4 w-4" />
              Upload an Image
            </Button>
          )
        }}
      </CldUploadWidget>
    </div>
  )
}

export default ImageUpload

我尝试了这个,它可以预览两个图像,但随后我收到一个错误,它需要一个数组而不是一个函数:

 const handleImageChange = (url: string) => {
                // Update the form state with the new images array
                field.onChange((prev: Image[]) => [...(prev || []), { url }])
              }

              // Handle image removal
              const handleImageRemove = (url: string) => {
                // Update the form state with the filtered images array
                field.onChange((prev: Image[]) => (prev || []).filter((image) => image.url !== url) as Image[])
              }

next.js cloudinary shadcnui react-forms
1个回答
0
投票

我面临着同样的问题,但这样做解决了它:

<ImageUpload
  value={field.value.map((image)=>image.url)}
  disabled={isLoading}
  onChange={(url) => {
       const currentImages = form.getValues("images");
       field.onChange([...currentImages, {url}])
}
}
  onRemove=
{(url)=>field.onChange([...field.value.filter((image)=>image.url!=url)])}                                    />
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.