简体   繁体   中英

How do I delete dynamically rendered component that is part of a list?

I currently dynamically render the same component when clicking a button and the latest component is rendered on the top of the list.

Now, I want to delete the component. Each component has a cancel button to delete the rendered component. So I should be able to delete the component no matter where it is in the list.

Here's what I have so far:

local state:

state = {
    formCount: 0
}

add and cancel:

onAddClicked = () => {
    this.setState({formCount: this.state.formCount + 1});
}

onCancelButtonClicked = (cancelledFormKey: number) => {
    const index = [...Array(this.state.formCount).keys()].indexOf(cancelledFormKey);

    if (index > -1) {
      const array = [...Array(this.state.formCount).keys()].splice(index, 1);
    }
}

Parent component snippet:

{ [...Array(this.state.formCount).keys()].reverse().map(( i) =>
                            <Form key={i} 
                                      onCancelButtonClicked={() => this.onCancelButtonClicked(i)}
                            />)
                        }

The only thing is I'm not sure how to keep track of which form was cancelled/deleted. I think I would need to create a new object in my local state to keep track but how do I know which index of the array I deleted as part of state? I'm not sure how do that? As I am using the count to make an array above.

Usually, this isn't how you'd generate a list of items. You're not storing the form data in the parent, and you're using index based keys which is a no-no when you're modifying the array. For example, I have an array of size 5 [0, 1, 2, 3, 4], when I remove something at position 2, the index of all the items after it changes causing their key to change as well, which will make react re-render them. Since you're not storying the data in the parent component, you will lose them.

Just to humor you, if we want to go with indexed based keys, we may have to maintain a list of removed indexes and filter them out. Something like this should do the trick:

state = {
    formCount: 0,
    deletedIndex: []
}


onCancelButtonClick = (cancelledIndex: number) => setState((prevState) => ({
         deletedIndex: [...prevState.deletedIndex, cancelledIndex]
});

And your render would look like:

{ 
    [...Array(this.state.formCount)].keys()].reverse().map((i) => (
        if (deletedIndex.includes(i) {
            return null;
        } else {
            <Form key={i} ... />   
        }
    ))
}

As a rule of thumb though, avoid having index based keys even if you don't care about performance. It'll lead to a lot of inconsistent behavior, and may also cause the UI and the state to be inconsistent. And if you absolutely want to for fun, make sure the components that are being rendered using index based keys have their data stored at the parent component level

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM