facebookexperimental/Recoil

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

Open

Aperta il 28 mar 2022

Vedi su GitHub
 (1 commento) (3 reazioni) (0 assegnatari)JavaScript (19.428 star) (1151 fork)batch import
help wantedperformance

Descrizione

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);
});

Guida contributor