In this code I have the possibility to upload images and display them with a category for each one. The image and category are saved in an array. The problem is when I want to select a value of a dropdown, the value selected doesn´t change in the dropdown to see the value that I selected, but this value is saved when I clicked it in the array field in the dropdown.
import { faHandHoldingUsd, faTrash, faUpload } from '@fortawesome/free-solid-svg-icons';
import { Fragment, useCallback} from 'react'
import SetIcon from '../../../../Components/Forms/SetIcon';
import MessageError from '../../../../Components/MessageError';
import '../Css/FrmImages.css';
import { Image } from 'primereact/image';
import { Dropdown } from 'primereact/dropdown';
import { CATEGORIES } from '../../../../constants';
type Props={
setValue:any,
errors:any,
getValues:any,
watch:any,
control:any,
trigger:any,
}
const FrmImages : React.FC<Props> = ({setValue,errors,getValues,watch,control}) => {
const deleteHandler=useCallback((index_image:any)=>{
setValue('images',getValues('images').filter((e:any,index:any) => index !== index_image));
watch('images')
},
[setValue,getValues,watch],
)
const handleChange = (event:any) => {
let files = event.target.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader:any = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
const image = reader.result.split(',')[1];
//append({'arrayField.image':{image:'',product_image_type_id:0}})
setValue('images',getValues("images").concat({image}));
watch('images')
};
}
event.target.value="";
};
const handleCategoryChange = (index:any, event:any) => {
//--------------------LINEAS DE CODIGO PARA GUARDAR LA CATEGORIA EN EL ARREGLO QUE SE VA A ENVIAR EN EL FORMULARIO EN EL PARAM images-----------------------
const newCategories = [...getValues('images')];
newCategories[index].product_image_type_id = Number(event.value);
console.log(newCategories);
//setValue('images',newCategories);
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
};
const ImageError = () => {
return (
<div>
{ errors.images && errors.images.length ? errors.images.map((image:any, index:any)=>{
return (
<div key={index}>
<MessageError name={image?.product_image_type_id} message={image?.product_image_type_id ? 'La imagen ' + (index + 1) + ' ' + image.product_image_type_id?.message : '' }/>
</div>
)
}) :
<></>
}
</div>
)
}
return (
<div>
<div>
<label className='label-upload'>
<SetIcon icon={faUpload}/>Subir
<span> Hasta 10 imagenes</span>
<input
className='input-file'
type="file"
onChange={handleChange}
multiple
accept="image/*"
/>
</label>
<div className="images">
{
getValues('images').map((image:any, index:any) => {
return (
<div key={index}>
<div className="image">
<Image src={`data:image/png;base64,${image.image}`} height="130" width='150' alt="upload" preview className='image-base64'/>
<div className='grid-delete'>
<button onClick={() => deleteHandler(index)} >
<SetIcon icon={faTrash} className='icon-trash'/>
</button>
<Dropdown optionLabel="name" optionValue="id" value={image.product_image_type_id} options={CATEGORIES} onChange={(e) => handleCategoryChange(index,e)} placeholder="Select a City"/>
<span className='indice'> {index+1}</span>
</div>
</div>
</div>
)
})
}
</div>
<ImageError/>
{getValues('images').length > 0 &&
(getValues('images').length > 10 && (
<p className="error">
No se permite subir mas de 10 imagenes <br />
<span>
Por valor elimina <b> {getValues('images').length - 10} </b> de estas{" "}
</span>
</p>
))}
</div>
</div>
)
}
export default FrmImages
I expected that when I clicked an option of just one dropdown, I can see the value that I selected in the dropdown. Usually this process commonly is done with a useState in the onChange event to manage the change in the state, but unfortunately due to I have more than one dropdown, the selected value appears in all the dropdowns. Thanks for helping me.