Reactjs: Delete function removing too many elements from dynamic array of components

Viewed 59

I am building a component that records the times entered against an activity and a task for that activity.

The "Delete" button (the X on the left) isn't working as intended, which is to remove the single weekPanel component that the button belongs to from the array 'weekPanels. Currently, it removes the panel that is clicked on, but also removes all the following panels.

I have a demonstration here: https://jscomplete.com/playground/s409549

The components states:

const [weekId, setWeekId] = useState(100);
    const [weekPanels, setWeekPanels] = useState([]);
    const [monday, setMonday] = useState(0);
    const [tuesday, setTuesday] = useState(0);
    const [wednesday, setWednesday] = useState(0);
    const [thursday, setThursday] = useState(0);
    const [friday, setFriday] = useState(0);
    const [saturday, setSaturday] = useState(0);
    const [sunday, setSunday] = useState(0);

The "Add Activity/Task button adds a WeekPanel component to the weekPanels state. Then updates the weekId.

const addWeekPanel = () => {
        setWeekPanels(weekPanels.concat(
            <WeekPanel
                key={weekId}
                weekId={weekId}
                weekPanels={weekPanels}
                activitiesList={props.activitiesList}
                tasksList={props.tasksList}
                monday={monday}
                tuesday={tuesday}
                wednesday={wednesday}
                thursday={thursday}
                friday={friday}
                saturday={saturday}
                sunday={sunday}
                handleHoursChange={handleHoursChange}
                handleWeekPanelDelete={handleWeekPanelDelete}
                activityTask={{}}
            />));
        setWeekId(weekId + 1);
    }

Which does the job sufficiently.

Here is the delete function: (the logging is stripped out)

const handleWeekPanelDelete = deleteId => {

        const newWeekPanels = weekPanels.filter(week => week !== deleteId);

        setWeekPanels(newWeekPanels);
    }

It also has a strange interaction, that is, with a console.log out of the state at various points, the logging shows the result of the delete, before the weekPanels.filter() has been reached.

1 Answers

Try using splice instead, It returns the array after item has been removed( remove one element from the index specified)

 const handleWeekPanelDelete = deleteId => {
         weekPanels.splice(deleteId, 1);  
         setWeekPanels(weekPanels);
 }

Or with your exisitng code , use this variant of filter(i specifies index of the current element being processed in the array).

 const handleWeekPanelDelete = deleteId => {     
        let newWeekPanels = weekPanels.filter((x, i)=> i!==deleteId);
        setWeekPanels(newWeekPanels);
 }
Related