facebookexperimental/Recoil

waitForAll does not prevent component re-renders while it is waiting

Open

#1.698 aberto em 28 de mar. de 2022

Ver no GitHub
 (1 comment) (3 reactions) (0 assignees)JavaScript (1.151 forks)batch import
help wantedperformance

Métricas do repositório

Stars
 (19.428 stars)
Métricas de merge de PR
 (Nenhuma PRs mesclada em 30d)

Description

Example taken from the documentation

https://recoiljs.org/docs/guides/asynchronous-data-queries#concurrent-requests

const currentUserIDState = atom({
  key: 'CurrentUserID',
  default: null,
});

const userInfoQuery = selectorFamily({
  key: 'UserInfoQuery',
  get: userID => async () => {
    const response = await myDBQuery({userID});
    if (response.error) {
      throw response.error;
    }
    return response;
  },
});

const currentUserInfoQuery = selector({
  key: 'CurrentUserInfoQuery',
  get: ({get}) => get(userInfoQuery(get(currentUserIDState))),
});

const friendsInfoQuery = selector({
  key: 'FriendsInfoQuery',
  get: ({get}) => {
    const {friendList} = get(currentUserInfoQuery);
    const friends = get(waitForAll(
      friendList.map(friendID => userInfoQuery(friendID))
    ));
    return friends;
  },
});

With this design, a component with useRecoilValue(friendsInfoQuery) is re-rendered every time that await myDBQuery({userID}) is resolved.

My expectation is get(waitForAll) would wait for all of these await statements to complete before triggering a component render with the final result, in a similar manner to this pattern:

const [friendsList, setFriendsList] = useState([]);

Promise.all(getFriendQueries).then((result) => {
  setFriendsList(result);
});

Guia do colaborador