简体   繁体   English

如何在 React 中为动态渲染的组件设置状态变量

[英]How to set a state varibale for a dynamically rendered component in React

I have an array full of user data I'm mapping though to display its information, and I'd like to have a button for each watchlist that deletes that watchlist (the backend already works I tested the deleteWatchlist function with the string value of an existing watchlist).我有一个充满用户数据的数组,但我正在映射以显示其信息,并且我希望每个监视列表都有一个按钮来删除该监视列表(后端已经工作,我使用字符串值测试了deleteWatchlist函数现有的监视列表)。 My problem is that I get the name of the watchlist I need after mapping through the first array.我的问题是我在映射到第一个数组后得到了我需要的监视列表的名称。

How do I set the state of the watchlistName for each watchlist?如何为每个监视列表设置 watchlistName 的状态?

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;

You needn't use state for this in your dynamically rendered component on each iteration pass the current watchlist ( i.watchlistName ) into the function as a parameter.您不需要在每次迭代时在动态呈现的组件中使用状态,将当前监视列表 ( i.watchlistName ) 作为参数传递到函数中。 To do this update your code as follows:为此,请按如下方式更新您的代码:

NOTE: Also note that async functions in a syncronous context returns a promise.注意:还要注意同步上下文中的异步函数返回一个承诺。

deleteWatchList删除监视列表

 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);
    }
  };

delete button删除按钮

          <button type="button" onClick={()=>deleteWatchlist(i.watchlistName)}>
            delete
          </button>

If it so happens that react does not trigger a re-render on the axios API call response add the following code to the deleteWatchList function:如果碰巧 react 不会在axios API 调用响应上触发重新渲染,请将以下代码添加到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);
    }
  };

Recommendation on Rest API endpoints关于 Rest API 端点的建议

Rest API is a semantic model for very specific purposes, this is so that one endpoint represents a CRUD (Create, Retrieve, Update, Delete). Rest API 是一种用于非常特定目的的语义模型,因此一个端点代表一个CRUD (创建、检索、更新、删除)。

Instead of exposing the endpoint as http://localhost:5000/api/users/${session?.id}/deletewatchlist using a POST update your API to accept calls on the 'DELETE' method.而不是使用POST将端点公开为http://localhost:5000/api/users/${session?.id}/deletewatchlist更新您的 API 以接受对“DELETE”方法的调用。

And update the endpoint to http://localhost:5000/api/userwahtchlist .并将端点更新为http://localhost:5000/api/userwahtchlist

Make the session.id the cookie and retreive the cookie on the request object in your web api.使 session.id 成为 cookie 并在您的 web api 中的请求对象上检索 cookie。 (will be something like req.cookie if you are perhaps using express . (如果您可能正在使用express则类似于req.cookie

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM