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 (19.428 stars) (1.151 forks)batch import
help wantedperformance

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