这是我的表单字段,我将图像传递给 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[])
}
我面临着同样的问题,但这样做解决了它:
<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)])} />