¿Cómo eliminar un solo elemento de Firebase en tiempo real en la aplicación de reacción?

¿Puede alguien ayudarme a eliminar un solo elemento de la base de datos en tiempo real usando la función remove () siguiendo este código? Dice que 'id' no está definido Gracias)

import { expensesRef } from '../firebase';

const ExpenseItem = (props) => {

    const handleDeleteExpense = (id) => {
        
        expensesRef.child(`expenses/` + id).remove();
    };

    return (
        <li class='list-group-item d-flex justify-content-between align-items-center'>
            {props.name}
            <div>
                <span class='badge badge-success mr-3'>{props.priority}</span>
                <span class='badge badge-info mr-3'>{props.cost} Lei</span>
                <TiDelete size='1.5em' onClick={handleDeleteExpense(`${id}`)} />
            </div>
        </li>
    );
};

export default ExpenseItem;

Así es como se ve mi base de datos

Answer

En aras de la explicación, voy a eliminar la handleDeleteExpensefunción de su código, dejándola con:

const ExpenseItem = (props) => {
    return (
        <li class='list-group-item d-flex justify-content-between align-items-center'>
            {props.name}
            <div>
                <span class='badge badge-success mr-3'>{props.priority}</span>
                <span class='badge badge-info mr-3'>{props.cost} Lei</span>
                <TiDelete size='1.5em' onClick={handleDeleteExpense(`${id}`)} />
            </div>
        </li>
    );
};

Aquí puede ver que la única referencia puntual idestá en el TiDeletecomponente. Lo más probable es que tuviera la intención idde ser configurado por el componente principal como lo está haciendo para name, priorityy cost. Por lo tanto, debe cambiar ida props.id.

Luego, en el componente principal, lo agregaría usando algo similar a:

const { name, priority, cost } = ref.val();
<ExpenseItem
  id=snapshot.key
  name=name
  priority=priority
  cost=cost
/>

o el más corto

<ExpenseItem
  { ...snapshot.val() }
  id=snapshot.key
/>

Es importante tener en cuenta que la clave de la instantánea, no su identificación dentro de sus datos, es lo que se transmite. Si usó la otra identificación, handleDeleteExpenseno funcionará.

A continuación, esta línea hará que sus datos se eliminen tan pronto como su componente se represente porque está llamando a la función de inmediato:

<TiDelete size='1.5em' onClick={handleDeleteExpense(`${id}`)} />

En su lugar, debería ser:

<TiDelete size='1.5em' onClick={() => handleDeleteExpense(`${id}`)} />

También importa una referencia llamada expensesRef, que supongo que se ha inicializado con firebase.database().child('expenses'). Esto significa que su instrucción de eliminación también está eliminando expenses/expenses/<id>en lugar de expenses/<id>.