How to properly remove an input file element from a rendered List in React?

129 views Asked by At

In my react Project, user have a Add button and when clicking on it new Input fields appear(1 for text input and other for file input). After user added some input fields and select files on them, He can remove an element by clicking remove button. But after removing , the input text field is properly removed and reordered, but the input file filed holding previous value.

enter image description here

If user click remove button on First row: enter image description here

Notice that First text field is properly removed, but input file filed is not properly set rather the last one is removed. How can I fix this.

const [fileuploadFields,setFileuploadFields] = useState([
    {type: '', file: ''},
]);
const addFields = () => {
    let object = {
        type: '',
        file: ''
    }

    setFileuploadFields([...fileuploadFields, object]);
}

and in the component div:

<div>
            <div className="mb-1">
                <Label text="Upload Attachment" />
            </div>
            {fileuploadFields.map((form, index) => {
                return (
                    <div className="flex mb-2" key={index}>
                        
                        <input 
                        name="type"
                        placeholder="File type (e.g: SLA)"
                        onChange={event => handleFileTypeTextChange(event, index)}
                        value={form.type}
                        required
                        />

                        <input 
                        name="file"
                        onChange={event => handleFileChange(event, index)}
                        type="file"
                        required
                        />
                {fileuploadFields.length>1 && 
                            (<button 
                                className="ml-2" type="button"
                                onClick={() => removeField(index)}
                            >
                                <FaMinusCircle className="text-primary" title="Remove"></FaMinusCircle>
                            </button>)
                        }

Remove method

       const removeField = (index) => {
        console.log(index);
        let data = [...fileuploadFields];
        data.splice(index,1);
        setFileuploadFields(data);
}

Please help, how can I fix this.

1

There are 1 answers

0
MMSmmsbd On

as @cmgchess suggested, setting a unique key value in the rendered list has solved the problem rather than index as the key. First the updated list is set like this:

const [fileuploadFields,setFileuploadFields] = useState([
        {id: uuidv4(), type: '', file: null},
]);

method for adding extra fields:

const addFields = () => {
        let object = {
            id: uuidv4(),
            type: '',
            file: null
        }

        setFileuploadFields([...fileuploadFields, object]);
    }

and the rendered component is:

{fileuploadFields.map((form) => {
            return (
                <div className="flex mb-2" key={form.id}>
                    
                    <input
                    name="type"
                    placeholder="File type (e.g: SLA)"
                    onChange={event => handleFileTypeTextChange(event, form.id)}
                    value={form.type}
                    required
                    />

                    <input
                    name="file"
                    onChange={event => handleFileChange(event, form.id)}
                    type="file"
                    required
                    />
                    
                    {fileuploadFields.length>1 && 
                        (<button 
                            className="ml-2" type="button"
                            onClick={() => removeField(form.id)}
                        >
                            <FaMinusCircle className="text-primary" title="Remove"></FaMinusCircle>
                        </button>)
                    }
                </div>
            )
        })}

form.id is set as key, which is set in fileuploadFields list.