I am trying to submit a form that has 4 form fields.
export type ChapterData = {
chapterNumber: number;
volumeNumber?: number;
chapterName?: string;
chapterImages: ImageListType;
};
I have made a custom hook, useAddChapterForm.
The initial state is as:
const initialState: ChapterData = {
chapterNumber: 0,
volumeNumber: 0,
chapterName: '',
chapterImages: [],
};
I want to update the state of all these elements in a single state and have used this approach.
const [chapterData, setChapterData] = useState<ChapterData>(initialState);
const changeHandler = (e: ChangeEvent<HTMLInputElement>) => {
setChapterData({ ...chapterData, [e.target.name]: e.target.value });
};
But I want to handle the change of the chapterImages differently.
So, my hook looks like so.
export const useAddChapterForm = () => {
const [chapterData, setChapterData] = useState<ChapterData>(initialState);
const [images, setImages] = useState([]);
const maxNumber = 69;
const onChangeImageHandler = (imageList: ImageListType, addUpdateIndex: number[] | undefined) => {
console.log(imageList, addUpdateIndex);
setImages(imageList as never[]);
setChapterData({ ...chapterData, [chapterData.chapterImages]: imageList });
};
const changeHandler = (e: ChangeEvent<HTMLInputElement>) => {
setChapterData({ ...chapterData, [e.target.name]: e.target.value });
};
return {
chapterData,
maxNumber,
changeHandler,
images,
onChangeImageHandler,
};
};
I want to set the value of chapterImages when there is a change in with onChangeImageHandler so I am able to remove the images too.
setChapterData({ ...chapterData, [chapterData.chapterImages]: imageList });
There is a typescript error. So, how do I change the state of this key chapterData.chapterImageswith setState?
Updated the question as per suggested answer:
const onChangeImageHandler = (imageList: ImageListType, addUpdateIndex: number[] | undefined) => {
console.log(imageList, addUpdateIndex);
setImages(imageList as never[]);
setChapterData({ ...chapterData, chapterImages: imageList });
};
const changeHandler = (e: ChangeEvent<HTMLInputElement>) => {
setChapterData({ ...chapterData, [e.target.name]: e.target.value });
};
Here is handle submit:
const { chapterData, changeHandler } = useAddChapterForm();
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
console.log(chapterData);
};
return (
<form onSubmit={handleSubmit}>
...
I am using this component to upload the image.
export const ImageUploadField: FunctionComponent<ImageUploadFieldProps> = (
props: ImageUploadFieldProps
) => {
const { error } = props;
const { images, onChangeImageHandler, maxNumber } = useAddChapterForm();
return (
<FieldWrapper label={'Select cover image'} errorMessage={error}>
<ImageUploading multiple value={images} onChange={onChangeImageHandler} maxNumber={maxNumber}>
{({
imageList,
onImageUpload,
onImageRemoveAll,
onImageUpdate,
onImageRemove,
isDragging,
dragProps,
}) => (
<div className="outline-dashed outline-2 outline-offset-2">
{imageList.length === 0 && (
<button
className="w-full text-center"
style={isDragging ? { color: 'red' } : undefined}
onClick={onImageUpload}
{...dragProps}
>
Click or Drop here
</button>
)}
<div className="flex flex-col justify-center">
{imageList.length > 0 && (
<div className="px-2 py-1 rounded bg-red-500 flex">
<button className=" space-x-2 w-full" onClick={onImageRemoveAll}>
Remove all images
</button>
<XCircle />
</div>
)}
<div className="flex flex-wrap">
{imageList.map((image, index) => (
<div key={index} className="flex">
<div className="flex flex-col p-2">
<Image
src={image.dataURL as string}
alt={image.file?.name}
width={150}
height={200}
quality={65}
className="rounded-tl rounded-bl"
/>
<p>{image.file?.name}</p>
<div className="flex space-x-4">
<div className="flex px-2 py-1 rounded bg-green-500 space-x-2">
<button onClick={() => onImageUpdate(index)}>Update</button>
<PencilEdit />
</div>
<div className="flex px-2 py-1 rounded bg-red-500 space-x-2">
<button onClick={() => onImageRemove(index)}>Remove</button>
<XCircle />
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
)}
</ImageUploading>
</FieldWrapper>
);
};

