英文:
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 "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("");
//get a list of users and their information. UserID is the key
//Data looks like this
// [ {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);
};
//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: "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} //show the title of the user
placement="right"
size={size}
onClose={onClose}
open={open}
// dataSource={user_list}
extra={
<Space>
{" "}
<Button type="primary" onClick={onClose}>
close
</Button>
</Space>
}
>
<Descriptions>
<Descriptions.Item label="E-Mail Address"> {email}</Descriptions.Item>
<Descriptions.Item label="Location">{location}</Descriptions.Item>
</Descriptions>
<Tabs
tabPosition={"left"}
defaultActiveKey="1"
items={items}
closable
/>
</Drawer>
</>
);
};
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) => {
const chosenUser = user_list?.find(user=>user.userId===userId) ?? null;
setSelectedUser(chosenUser);
setOpen(true);
};
And on the onclick function on the List
onClick={()=>showLargeDrawer(item.userId)}
Finally on the Description you simply show the properties of the 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>
With this additions to your code it will work the way you want to.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论