从React antd中的列表传递值给抽屉

huangapple go评论63阅读模式
英文:

Passing value to drawer from a list in React antd

问题

我有一个显示客户列表及其详细信息的功能。然而,当我点击客户的名称时,我希望打开一个抽屉。该抽屉内的数据应特定于客户(最初获取的数据)。此外,抽屉内有一个选项卡,根据用户ID获取客户的附加数据。我需要将userID从初始列表传递到抽屉。我被困在这里,因为我无法弄清楚如何在列表和抽屉之间建立连接。

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Button, Space, Descriptions, Tabs, List, Avatar, Drawer } from "antd";
import { BulbOutlined, MessageOutlined } from "@ant-design/icons";
import UserIdeas from "./UserIdeas";
import UserMessages from "./UserMessages";

const UserDrawer = () => {
  const [user_list, getData] = useState("");

  // 获取用户列表和他们的信息。UserID是关键
  // 数据看起来像这样
  // [
  //   {title: 'Ahmed xxx', userId: 1, email: 'ahmed@xx.com', location: 'Canada'},
  //   {title: 'Ahmed2 xxx', userId: 2, email: 'ahmed2@xx.com', location: 'Canada'},
  // ]

  const getAllData = () => {
    var user_access_token = localStorage.getItem("user_access_token");
    axios
      .get(process.env.REACT_APP_API_URL + "reports/product/1/users", {
        headers: {
          Authorization: "Bearer " + user_access_token,
        },
      })
      .then((response) => {
        const allData = response.data;
        getData(allData);
      })
      .catch((error) => console.error(error));
  };

  useEffect(() => {
    getAllData();
  }, []);

  const [open, setOpen] = useState(false);
  const [size, setSize] = useState();
  const showLargeDrawer = () => {
    setOpen(true);
  };
  const onClose = () => {
    setOpen(false);
  };

  // 选项卡菜单。需要将每个客户的UserID传递到组件,以显示与用户关联的数据
  const items = [
    {
      key: "1",
      label: (
        <span>
          <BulbOutlined /> Ideas
        </span>
      ),
      children: <UserIdeas user_id={item.userId} />,
    },
    {
      key: "2",
      label: (
        <span>
          <MessageOutlined /> Comments
        </span>
      ),
      children: <UserMessages user_id={item.userId} />,
    },
  ];

  return (
    <>
      <List
        itemLayout="vertical"
        dataSource={user_list}
        renderItem={(item) => (
          <List.Item>
            <List.Item.Meta
              title={
                <a onClick={showLargeDrawer} key={`a-${item.userId}`}>
                  {item.title}
                </a>
              }
            />
          </List.Item>
        )}
      />

      <Drawer
        title={item.title} // 显示用户的标题
        placement="right"
        size={size}
        onClose={onClose}
        open={open}
        // dataSource={user_list}
        extra={
          <Space>
            {" "}
            <Button type="primary" onClick={onClose}>
              关闭
            </Button>
          </Space>
        }
      >
        <Descriptions>
          <Descriptions.Item label="电子邮件地址">{email}</Descriptions.Item>
          <Descriptions.Item label="地点">{location}</Descriptions.Item>
        </Descriptions>

        <Tabs
          tabPosition="left"
          defaultActiveKey="1"
          items={items}
          closable
        />
      </Drawer>
    </>
  );
};

export default UserDrawer;
英文:

I have a function that shows a list of customers and their details. However, when I click on the name of the customer, I want a drawer to open. The data within that draw should be specific to the customer (which I originally fetched). Plus I have a tab within the drawer that will fetch additional data for the customer based on their userID. I need this userID passed on from the initial list to the Drawer. I am stuck here because I am unable to figure out how to make that connection between the list and the Drawer.

import React, { useState, useEffect } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import { Button, Space, Descriptions, Tabs, List, Avatar, Drawer } from &quot;antd&quot;;
import { BulbOutlined, MessageOutlined } from &quot;@ant-design/icons&quot;;
import UserIdeas from &quot;./UserIdeas&quot;;
import UserMessages from &quot;./UserMessages&quot;;

const UserDrawer = () =&gt; {
  const [user_list, getData] = useState(&quot;&quot;);

  //get a list of users and their information. UserID is the key
  //Data looks like this
  // [  {title: &#39;Ahmed xxx&#39;, userId:1, email: &#39;ahmed@xx.com&#39; , location: &#39;Canada&#39;  },  {title: &#39;Ahmed2 xxx&#39;, userId:2, email: &#39;ahmed2@xx.com&#39; , location: &#39;Canada&#39;  },]

  const getAllData = () =&gt; {
    var user_access_token = localStorage.getItem(&quot;user_access_token&quot;);
    axios
      .get(process.env.REACT_APP_API_URL + &quot;reports/product/1/users&quot;, {
        headers: {
          Authorization: &quot;Bearer &quot; + user_access_token,
        },
      })
      .then((response) =&gt; {
        const allData = response.data;
        getData(allData);
      })
      .catch((error) =&gt; console.error(error));
  };

  useEffect(() =&gt; {
    getAllData();
  }, []);

  const [open, setOpen] = useState(false);
  const [size, setSize] = useState();
  const showLargeDrawer = () =&gt; {
    setOpen(true);
  };
  const onClose = () =&gt; {
    setOpen(false);
  };

  //Menu of the Tabs. Need to pass the UserId for each customer to the component to display the data associated with the user
  const items = [
    {
      key: &quot;1&quot;,
      label: (
        &lt;span&gt;
          &lt;BulbOutlined /&gt; Ideas
        &lt;/span&gt;
      ),
      children: &lt;UserIdeas user_id={item.userId} /&gt;,
    },
    {
      key: &quot;2&quot;,
      label: (
        &lt;span&gt;
          &lt;MessageOutlined /&gt; Comments
        &lt;/span&gt;
      ),
      children: &lt;UserMessages user_id={item.userId} /&gt;,
    },
  ];

  return (
    &lt;&gt;
      &lt;List
        itemLayout=&quot;vertical&quot;
        dataSource={user_list}
        renderItem={(item) =&gt; (
          &lt;List.Item&gt;
            &lt;List.Item.Meta
              title={
                &lt;a onClick={showLargeDrawer} key={`a-${item.userId}`}&gt;
                  {item.title}
                &lt;/a&gt;
              }
            /&gt;
          &lt;/List.Item&gt;
        )}
      /&gt;

      &lt;Drawer
        title={item.title} //show the title of the user
        placement=&quot;right&quot;
        size={size}
        onClose={onClose}
        open={open}
        // dataSource={user_list}
        extra={
          &lt;Space&gt;
            {&quot; &quot;}
            &lt;Button type=&quot;primary&quot; onClick={onClose}&gt;
              close
            &lt;/Button&gt;
          &lt;/Space&gt;
        }
      &gt;
        &lt;Descriptions&gt;
          &lt;Descriptions.Item label=&quot;E-Mail Address&quot;&gt; {email}&lt;/Descriptions.Item&gt;
          &lt;Descriptions.Item label=&quot;Location&quot;&gt;{location}&lt;/Descriptions.Item&gt;
        &lt;/Descriptions&gt;

        &lt;Tabs
          tabPosition={&quot;left&quot;}
          defaultActiveKey=&quot;1&quot;
          items={items}
          closable
        /&gt;
      &lt;/Drawer&gt;
    &lt;/&gt;
  );
};

export default UserDrawer;

答案1

得分: 1

你需要一些东西来在抽屉上显示正确的数据。首先,添加一个状态来存储在列表中选择的用户索引。

const [selectedUser, setSelectedUser] = useState(null);

默认情况下,不会选择任何用户。

你还需要更改 showLargeDrawer 函数,类似于以下方式,在这里你获取 userId 与点击的项目上的 userId 相同的元素,将其存储在 selectedUser 中并将 setOpen 设置为 true。

const showLargeDrawer = (userId) => {
  const chosenUser = user_list?.find(user => user.userId === userId) ?? null;
  setSelectedUser(chosenUser);
  setOpen(true);
};

在列表的点击函数上:

onClick={() => showLargeDrawer(item.userId)}

最后,在描述部分,你只需显示 selectedUser 的属性。

<Descriptions>
  <Descriptions.Item label="E-Mail Address">
    {selectedUser?.email ?? 'No email found'}
  </Descriptions.Item>
  <Descriptions.Item label="Location">
    {selectedUser?.location ?? 'No location found'}
  </Descriptions.Item>
</Descriptions>

通过将这些内容添加到你的代码中,它将按照你想要的方式工作。

英文:

You need a couple of things to show the correct data on the drawer. The first one is to add a state that stores the selected user index on your list.

const [selectedUser, setSelectedUser] = useState(null);

By default no user will be selected

You also have to change the function showLargeDrawer to something like this, where you get the element where userId is the same that the one on the clicked item, store it on selectedUser and setOpen to true

const showLargeDrawer = (userId) =&gt; {
const chosenUser = user_list?.find(user=&gt;user.userId===userId) ?? null;
setSelectedUser(chosenUser);
setOpen(true);
};

And on the onclick function on the List

onClick={()=&gt;showLargeDrawer(item.userId)}

Finally on the Description you simply show the properties of the selectedUser

&lt;Descriptions&gt;
&lt;Descriptions.Item label=&quot;E-Mail Address&quot;&gt;
{selectedUser?.email ?? &#39;No email found&#39;}
&lt;/Descriptions.Item&gt;
&lt;Descriptions.Item label=&quot;Location&quot;&gt;
{selectedUser?.location ?? &#39;No location found&#39;}
&lt;/Descriptions.Item&gt;
&lt;/Descriptions&gt;

With this additions to your code it will work the way you want to.

huangapple
  • 本文由 发表于 2023年2月27日 06:50:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575473.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定