如何将函数传递给数组中的每个映射项?
How to pass a function to each mapped items from an array?
在一个组件上,我映射了来自 API 的数组中的每个项目,然后 return 将它们分别放在 <li>
上,如下所示:
const usersComponent = usersData.map((user: any) => (
<li
key={user.Username}
className="px-4 my-2 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100"
>
\ rest of the code
然后,在组件上,我做:
return (
<ul>{usersComponent}</ul>
)
现在,此列表中的每个项目在我的 API 中都是 username
,并且这些用户名在我的数据库中有组,但组仅 return 在另一个 GET 中API,我在这个其他功能上有:
async function listGroupsForUser(username: string) {
const apiName = 'AdminQueries'
const path = '/listGroupsForUser'
const myInit = {
body: {
username
},
headers: {
'Content-Type': 'application/json',
Authorization: `${(await Auth.currentSession())
.getAccessToken()
.getJwtToken()}`,
},
}
return await API.get(apiName, path, myInit)
}
所以,我需要为我映射的每个 <li>
传递这个 listGroupsForUser
,然后它将 return 为每个映射一个数组,我需要映射它,对于每一个,单独。
试了很多方法都做不到
取决于您是否需要预先获取所有数据,或者您是否可以异步获取组。
要提前获取它们,您可以使用 Promise.All 并并行触发查询,例如:
const getRandomDelay = (min: number, max: number): number => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min);
};
// mock API call
const fetchGroups = (username: string): Promise<string[]> => {
return new Promise((resolve) => {
setTimeout(() => {
return resolve(['admin', 'editor']);
}, getRandomIntInclusive(2000, 4000));
});
};
const data = ['darth', 'fett', 'luke'];
interface User {
name: string;
groups?: string[];
}
export default function App() {
const [users, setUsers] = useState<User[] | null>(null);
useEffect(() => {
Promise.all(
data.map(async (user) => {
const groups = await fetchGroups(user);
return {
name: user,
groups: groups
};
})
).then((result) => {
setUsers(result);
});
}, []);
return (
<div className="App">
{users &&
users.map((user) => (
<div key={user.name}>
{user.name}
{user.groups.map((group) => (
<span key={group}>{group}, </span>
))}
</div>
))}
</div>
);
}
或者,您可以在每个中使用一个挂钩。类似于:
const useListGroupsForUser = (username: string) => {
const [groups, setGroups] = useState<string[] | null>(null);
useEffect(() => {
console.info(`mocking fetch for ${username}`);
fetchGroups(username).then((result) => setGroups(result));
}, [username]);
return {
groups
};
};
// User component
const User = ({ user }: UserProps) => {
const { groups } = useListGroupsForUser(user);
return (
<li>
{user} <br />
{groups ? groups.map((group) => group) : <span>loading groups...</span>}
</li>
);
};
// and render in App
{data.map((user) => (
<User key={user} user={user}/>
))}
在一个组件上,我映射了来自 API 的数组中的每个项目,然后 return 将它们分别放在 <li>
上,如下所示:
const usersComponent = usersData.map((user: any) => (
<li
key={user.Username}
className="px-4 my-2 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100"
>
\ rest of the code
然后,在组件上,我做:
return (
<ul>{usersComponent}</ul>
)
现在,此列表中的每个项目在我的 API 中都是 username
,并且这些用户名在我的数据库中有组,但组仅 return 在另一个 GET 中API,我在这个其他功能上有:
async function listGroupsForUser(username: string) {
const apiName = 'AdminQueries'
const path = '/listGroupsForUser'
const myInit = {
body: {
username
},
headers: {
'Content-Type': 'application/json',
Authorization: `${(await Auth.currentSession())
.getAccessToken()
.getJwtToken()}`,
},
}
return await API.get(apiName, path, myInit)
}
所以,我需要为我映射的每个 <li>
传递这个 listGroupsForUser
,然后它将 return 为每个映射一个数组,我需要映射它,对于每一个,单独。
试了很多方法都做不到
取决于您是否需要预先获取所有数据,或者您是否可以异步获取组。
要提前获取它们,您可以使用 Promise.All 并并行触发查询,例如:
const getRandomDelay = (min: number, max: number): number => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min);
};
// mock API call
const fetchGroups = (username: string): Promise<string[]> => {
return new Promise((resolve) => {
setTimeout(() => {
return resolve(['admin', 'editor']);
}, getRandomIntInclusive(2000, 4000));
});
};
const data = ['darth', 'fett', 'luke'];
interface User {
name: string;
groups?: string[];
}
export default function App() {
const [users, setUsers] = useState<User[] | null>(null);
useEffect(() => {
Promise.all(
data.map(async (user) => {
const groups = await fetchGroups(user);
return {
name: user,
groups: groups
};
})
).then((result) => {
setUsers(result);
});
}, []);
return (
<div className="App">
{users &&
users.map((user) => (
<div key={user.name}>
{user.name}
{user.groups.map((group) => (
<span key={group}>{group}, </span>
))}
</div>
))}
</div>
);
}
或者,您可以在每个中使用一个挂钩。类似于:
const useListGroupsForUser = (username: string) => {
const [groups, setGroups] = useState<string[] | null>(null);
useEffect(() => {
console.info(`mocking fetch for ${username}`);
fetchGroups(username).then((result) => setGroups(result));
}, [username]);
return {
groups
};
};
// User component
const User = ({ user }: UserProps) => {
const { groups } = useListGroupsForUser(user);
return (
<li>
{user} <br />
{groups ? groups.map((group) => group) : <span>loading groups...</span>}
</li>
);
};
// and render in App
{data.map((user) => (
<User key={user} user={user}/>
))}