Home > Back-end >  Nextjs - update another component when delete item from database (supabase)
Nextjs - update another component when delete item from database (supabase)

Time:12-19

I have a problem with update my parent component when I try delete item from database.

I create simply get items from my database:

const filter = useFilter((query) => query.eq("createDate", date), [date]);
  const [{ data, fetching, error }] = useSelect("payments_subitems", {
    filter,
  });

and I return by simply Map function.

BUT, I create another component to delete items from my database:

<RemoveItem id={date} />

const supabaseClient = useSupabaseClient();
  const removeAction = async () => {
    try {
      const { data, error } = await supabaseClient
        .from("payments_items")
        .delete()
        .eq("date", id);
      if (error) throw error;
    } catch (error: any) {
      alert(error.message);
    }
  };

and I return simple button:

<Button
  className="w-full text-white bg-red-600 hover:bg-red-700"
  onClick={() => removeAction()}
>
  {title}
</Button>

Delete action works correctly... but when I delete an item- the parent component doesn't change the list of items in my accordion listing :(

Anybody can help me?

I try to use useEffect but doesn't work :/ I don't know what I'm doing wrong :(

My parent component:

export function GetPaymentsSubitems({ date }: GetPaymentsSubitemsProps) {
  const filter = useFilter((query) => query.eq("createDate", date), [date]);
  const [{ data, fetching, error }] = useSelect("payments_subitems", {
    filter,
  });

  return (
    <>
      {data?.map(({ title, value }, index) => {
        return (
          <div key={index} className="flex justify-between">
            <div>{title}</div>
            <div>{value}</div>
          </div>
        );
      })}
    </>
  );
}

export function GetPaymentsAccordion({
  userId,
  children,
}: GetPaymentsAccordionProps) {
  const payments: any = useSelector<any>((state) => state.payments);
  const countReduxPayments = payments.payments.length;
  const filter = useFilter((query) => query.eq("author", userId), [userId]);
  const [{ data, fetching, error }] = useSelect("payments_items", {
    filter,
    pause: !userId,
  });

  const [expanded, setExpanded] = useState<string | false>(false);

  const handleChange =
    (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => {
      setExpanded(isExpanded ? panel : false);
    };

  if (error)
    return (
      <Alert severity="error">
        <AlertTitle>Błąd</AlertTitle>
        {error.message}
      </Alert>
    );
  if (fetching)
    return (
      <div className="flex items-center justify-center">
        <CircularProgress />
      </div>
    );
  if (data?.length === 0 && countReduxPayments === 0)
    return (
      <Alert severity="info">
        <AlertTitle>Brak danych</AlertTitle>
        Nie posiadasz żadnych płatności
      </Alert>
    );

  return (
    <>
      {data?.map(({ date }, index) => {
        return (
          <React.Fragment key={index}>
            <Accordion
              expanded={expanded === date}
              onChange={handleChange(date)}
              key={index}
            >
              <AccordionSummary expandIcon={<ExpandMoreIcon />}>
                {date}
              </AccordionSummary>
              <AccordionDetails>
                <GetPaymentsSubitems date={date} />
                <RemoveItem id={date} />
              </AccordionDetails>
            </Accordion>
            {children && children}
          </React.Fragment>
        );
      })}
    </>
  );
}

Thanks!

CodePudding user response:

You can add reexecute param under useSelect

const filter = useFilter((query) => query.eq("createDate", date), [date]);
  const [{ data, fetching, error }, reexecute] = useSelect("payments_subitems", {
    filter,
  });

And then add another prop with this function execution to refresh your data like below

<RemoveItem id={date} refresh={() => { reexecute() }}/>

And the final step is adding that refresh() prop into removeAction

const supabaseClient = useSupabaseClient();
  const removeAction = async () => {
    try {
      const { data, error } = await supabaseClient
        .from("payments_items")
        .delete()
        .eq("date", id);
      refresh(); //refresh your data here
      if (error) throw error;
    } catch (error: any) {
      alert(error.message);
    }
  };
  • Related