如何将函数传递给数组中的每个映射项?

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}&nbsp;
            {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}/>
))}