How can i add and remove components dinamically?

Viewed 43

I want to add and remove the components dynamically, so far just i can add, but when i tried to remove it remove too weird, lets say i dont want to remove just i would like to hide the components

import {
    MinusCircleOutlined,
    PlusOutlined,
} from '@ant-design/icons'

import { useState } from "react"

const MyInput = ({ index, removeInput }) => {
    return (<div >
            <Input placeholder="Email address" />
        <MinusCircleOutlined className="icon-left" onClick={() => { removeInput(index) }} />
    </div>
    )
}

const MyComponent = ({ }) => {
    const [form] = Form.useForm()
    const [index, setIndex] = useState(0)
    const [inputsFields, setInputsFields] = useState([])
    const [hiddenFields, setHiddenFields] = useState([])

    const AddInput = () => {
        const newInviteField = <MyInput index={index} removeInput={removeInput} />
        setInputsFields([...inputsFields, newInviteField])
        const newIndex = index + 1
        setIndex(newIndex)
    }

    const removeInput = (currentIndex) => {
        let a = hiddenFields
        a.push(currentIndex)
        setHiddenFields([...a])
    }

    return (
        <Card>
            <Form form={form} layout="vertical">
                <Form.Item className='form-item item-container'>
                    {inputsFields.map((item, index) => !hiddenFields.includes(index) && <div key={index}>{item}</div>)}
                </Form.Item>
                <Form.Item >
                    <a href="#" onClick={AddInput}>Add</a>                     
                </Form.Item>
            </Form>
        </Card>)
}

i tried to filter by the index, just showing the indexes does not into the hidden array !hiddenFields.includes(index)

the problem is when i am deleting, sometimes it is not deleting, sometimes other component is deleting

1 Answers

You should never use an array method index as key, if you modify the array. It has to be unique. When you delete element with index 2, the index 3 becomes index 2. This should not happend. You should not change the key prop value

The solution:

keep information about the inputs in the state, not the inputs itself.

// keep necessarry information for each input here. 
// Like id, name, hidden, maybe what to render. Whatever you want
const [inputsFields, setInputsFields] = useState([{
   id: 'name',
   hidden: false
}])

// and map them 
inputsFields.map(element => !element.hidden && <Input key={element.id} />)

When each element has unique id, you will delete the element with that id, not with the array map index

If you do not need that much info. Just make array of numbers in that state,

const counter = useRef(1)
const [inputsFields, setInputsFields] = []

 const AddInput = () => {
    counter.current += 1
    setInputsFields(oldInputs => [...oldInputs, counter.current])
 }
// and render them:
inputsFields.map(element => <Input key={element} />)
Related