Search code examples
reactjsreact-props

ReactJs always print the same id


I'm trying to create a table with some data in it and I have problem on printing the right id.

First I created the parent component with the table and all the relative elements.

Inside the <tbody> I'm running a map() function where it loops through the whole array and return for each object a <TaskRow /> component.

Array of objects

let maintenance_task = [
    {
        task_id: 1,
        task: 'task 1',
        description: '',
        date: '2020-02-02'
    },
    {
        task_id: 2,
        task: 'task 2',
        description: '',
        date: '2020-02-02'
    },
    {
        task_id: 3,
        task: 'task 3',
        description: '',
        date: '2020-02-02'
    },
    {
        task_id: 4,
        task: 'task 4',
        description: '',
        date: '2020-02-02'
    }
]

Parent component

<tbody id="list-tasks">
   {
      props.maintenance_task.map( (task, index) => {
         return (
            <TaskRow
               key={ index }
               task={ task } 
            />
         );
      })
   }
</tbody>

Child component.

import React from 'react';

function TaskRow(props) {

    const toggle_delete_task = (task_id) => {

        console.log(task_id);

        const confirm_remove_task = document.getElementById('remove-task');
        const loading_animation = document.getElementById('loading-animation-section');

        confirm_remove_task.classList.toggle('d-block');
        loading_animation.classList.toggle('d-block');
    }

    return (
        <tr>
            <td><p>{ props.task.task }</p></td>
            <td><p>{ props.task.description }</p></td>
            <td><p>{ props.task.date }</p></td>

            <td className="wrap-inputs-task">
                <input type="button" value="Edit" />
                <input type="button" value="Delete" onClick={ () => toggle_delete_task(props.task.task_id) } /> // delete button
            </td>

            <td id="remove-task" className="confirm-remove-task">
                <p>Are you sure you want to remove this task ?</p>

                <span>
                    <input type="button" value="Confirm" />
                    <input type="button" value="Cancel" onClick={ () => toggle_delete_task(props.task.task_id) } /> // cancel button
                </span>
            </td>
        </tr>
    );
}

export default TaskRow;

When I click delete button it runs toggle_delete_task() where it will print in the console the current task_id and show remove-task element.

The problem is after, when I click cancel button and run the same function toggle_delete_task() it will always print 1 in the console, which is the first task_id of the objects inside the array.


Solution

  • All of your remove-task element has the same id, that when you do document.getElementById('remove-task') it only select's the firs remove-task element which belongs to task 1.

    You have to give each of them a different ids, probably appending the current task's task_id.

    <td
      id={`remove-task-${props.task.task_id}`} // notice this
      className="confirm-remove-task"
    >
    ...
    

    Then on your toggle_delete_task, make sure to get the correct confirm_remove_task element.

    const toggle_delete_task = (task_id) => {
      console.log(task_id);
      
      const confirm_remove_task = document.getElementById(
        `remove-task-${props.task.task_id}`
      );
      
      ...
      };
    

    Or a cleaner approach is to create a variable for the remove-task element's id, and reference that when assigning and selecting the element by id.

    function TaskRow(props) {
      const removeTaskElementId = `remove-task-${props.task.task_id}`;
    ...