#javascript #reactjs #next.js #state
Вопрос:
У меня есть массив, полный пользовательских данных, которые я сопоставляю, чтобы отобразить его информацию, и я хотел бы иметь кнопку для каждого списка наблюдения, которая удаляет этот список наблюдения (серверная часть уже работает, я протестировал deleteWatchlist
функцию со строковым значением существующего списка наблюдения). Моя проблема в том, что я получаю имя списка наблюдения, которое мне нужно, после сопоставления с первым массивом.
Как установить состояние имени списка наблюдения для каждого списка наблюдения?
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) =gt; fetch(...args).then((res) =gt; 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 () =gt; { 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 lt;divgt;failedlt;/divgt;; if (!userData) return lt;divgt;loading data...lt;/divgt;; console.log(userData); return ( lt;div className="flex flex-col"gt; {userData.watchlists.map((i) =gt; ( lt;div key={i._id} className="flex flex-col bg-blue-200 m-1"gt; lt;p className="text-2xl text-blue-600"gt;{i.watchlistName}lt;/pgt; lt;button type="button" onClick={deleteWatchlist}gt; delete lt;/buttongt; {i.coins[0].coin.map((coin) =gt; { return ( lt;divgt; {/* lt;p key={coin.coinID}gt;{coin.coinID}lt;/pgt; */} lt;CoinInUserProfile coinID={coin.coinID} name={coin.name} symbol={coin.symbol} watchlistName={i.watchlistName} /gt; lt;/divgt; ); })} lt;/divgt; ))} lt;/divgt; ); } export default WatchlistContainer;
Ответ №1:
Вам не нужно использовать состояние для этого в вашем динамически отображаемом компоненте, на каждой итерации передавайте текущий список наблюдения ( i.watchlistName
) в функцию в качестве параметра. Для этого обновите свой код следующим образом:
ПРИМЕЧАНИЕ: Также обратите внимание, что асинхронные функции в синхронном контексте возвращают обещание.
Удалить список
const deleteWatchlist = async (watchlistName) =gt; { 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); } };
кнопка удалить
lt;button type="button" onClick={()=gt;deleteWatchlist(i.watchlistName)}gt; delete lt;/buttongt;
Если произойдет так, что react не вызовет повторную визуализацию axios
в ответе на вызов API, добавьте в deleteWatchList
функцию следующий код:
const deleteWatchlist = async () =gt; { 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=gt;{ // 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); } };
Рекомендации по конечным точкам API Rest
Rest API-это семантическая модель для очень специфических целей, это делается для того, чтобы одна конечная точка представляла собой
CRUD
(Создание, извлечение, Обновление, Удаление).Вместо того, чтобы показывать конечную точку как
http://localhost:5000/api/users/${session?.id}/deletewatchlist
использующуюPOST
обновление вашего API для приема вызовов метода «УДАЛИТЬ».И обновите конечную точку до
http://localhost:5000/api/userwahtchlist
.Сделайте так, чтобы session.id файл cookie и восстановите файл cookie для объекта запроса в вашем веб-api. (будет что-то вроде
req.cookie
, если вы, возможно, используетеexpress
).
Комментарии:
1. чтобы вызвать повторный рендеринг, не нужно ли мне обернуть это в useEffect( )?