Tengo una matriz llena de datos de usuario que estoy mapeando para mostrar su información, y me gustaría tener un botón para cada lista de seguimiento que elimine esa lista de seguimiento (el backend ya funciona. Probé la función deleteWatchlist con el valor de cadena de un lista de observación existente). Mi problema es que obtengo el nombre de la lista de seguimiento que necesito después de mapear la primera matriz.
¿Cómo configuro el estado de watchlistName para cada lista de seguimiento?
import axios from "axios"; import { useSession } from "next-auth/react"; import React, { useState } from "react"; import useSWR from "swr"; import CoinInUserProfile from "./CoinInUserProfile"; const fetcher = (...args) => fetch(...args).then((res) => res.json()); function WatchlistContainer() { const { data: session } = useSession(); const { data: userData, userError } = useSWR( `http://localhost:5000/api/users/${session?.id}`, fetcher ); const [watchlistName, setWatchlistName] = useState(); const deleteWatchlist = async () => { try { const res = await axios({ url: `http://localhost:5000/api/users/${session?.id}/deletewatchlist`, method: "PUT", data: { watchlistName: watchlistName, }, }); } catch (error) { console.log(error); } }; if (userError) return <div>failed</div>; if (!userData) return <div>loading data...</div>; console.log(userData); return ( <div className="flex flex-col"> {userData.watchlists.map((i) => ( <div key={i._id} className="flex flex-col bg-blue-200 m-1"> <p className="text-2xl text-blue-600">{i.watchlistName}</p> <button type="button" onClick={deleteWatchlist}> delete </button> {i.coins[0].coin.map((coin) => { return ( <div> {/* <p key={coin.coinID}>{coin.coinID}</p> */} <CoinInUserProfile coinID={coin.coinID} name={coin.name} symbol={coin.symbol} watchlistName={i.watchlistName} /> </div> ); })} </div> ))} </div> ); } export default WatchlistContainer;No necesita usar el estado para esto en su componente renderizado dinámicamente en cada iteración, pase la lista de seguimiento actual ( i.watchlistName ) a la función como parámetro. Para hacer esto, actualice su código de la siguiente manera:
NOTA: También tenga en cuenta que las funciones asíncronas en un contexto síncrono devuelven una promesa.
const deleteWatchlist = async (watchlistName) => { try { const res = await axios({ url: `http://localhost:5000/api/users/${session?.id}/deletewatchlist`, method: "PUT", data: { watchlistName }, // variable name same as key name can be used this way }); } catch (error) { console.log(error); } }; <button type="button" onClick={()=>deleteWatchlist(i.watchlistName)}> delete </button> Si sucede que la reacción no activa una nueva representación en la respuesta de llamada de la API de axios , agregue el siguiente código a la función deleteWatchList :
const deleteWatchlist = async () => { try { const res = await axios({ url: `http://localhost:5000/api/users/${session?.id}/deletewatchlist`, method: "PUT", data: { watchlistName: watchlistName, }, }); // Code to Add res.then(response=>{ // pull the deleted watchlist in the backend from the selected `user.watchLists` object in the current session. }) // Code to Add } catch (error) { console.log(error); } };Recomendación sobre los puntos finales de la API Rest
Rest API es un modelo semántico para propósitos muy específicos, esto es para que un punto final represente un
CRUD(Crear, Recuperar, Actualizar, Eliminar).En lugar de exponer el punto final como
http://localhost:5000/api/users/${session?.id}/deletewatchlistusando unPOST, actualice su API para aceptar llamadas en el método 'DELETE'.Y actualice el punto final a
http://localhost:5000/api/userwahtchlist.Haga que session.id sea la cookie y recupere la cookie en el objeto de solicitud en su API web. (será algo así como
req.cookiesi tal vez está usandoexpress).