Skip to content

FeedbackSet and example#4

Open
markotron wants to merge 1 commit intodemo-base-1from
feedback-set
Open

FeedbackSet and example#4
markotron wants to merge 1 commit intodemo-base-1from
feedback-set

Conversation

@markotron
Copy link
Copy Markdown
Owner

Implementation of Architecture requirements, Side effects, 9.

We generate a list of users: 10 rows with random numbers from 0 to 19. Numbers represent user IDs. We also have 2 buttons, TOGGLE COMPONENT, and RELOAD.

Screen Shot 2020-01-19 at 21 37 10

The Reload generates a new list with random IDs while Toggle component removes the component (it unmounts it).

The idea is to demonstrate multiple features:

  1. You send one request per ID and cache the response.
  2. Any request has 25% chance of failing. You should be able to manually retry any request that fails.
  3. If you unmount the component all in-flight requests should be canceled.
  4. When you reload the list:
    4.1. All in-flight requests that were needed for a previous list but are not needed now, are canceled.
    4.2. All in-flight requests that were needed for a previous list and are still needed should normally continue (note that they shouldn't be restarted).
    4.3. New requests that were not needed before but are needed now should be started.

Comment on lines +23 to +51
export function useFeedbackSet<State, Query>(
state: State,
query: (state: State) => Set<Query>,
effect: (query: Query) => Cleanup
) {
const activeEffects = useRef<Map<Query, Cleanup>>(new Map());

const newQueries = Array.from(query(state));
const currentQueries = Array.from(activeEffects.current.keys());
const queriesToDelete = currentQueries.filter(currentQuery => !newQueries.includes(currentQuery));
const queriesToAdd = newQueries.filter(newQuery => !currentQueries.includes(newQuery));

queriesToDelete.forEach(toDelete => {
const effectToDelete = activeEffects.current.get(toDelete) ?? unsupported("Effect must be present!");
effectToDelete(); // Run the cleanup function.
activeEffects.current.delete(toDelete);
});

queriesToAdd.forEach(toAdd => activeEffects.current.set(toAdd, effect(toAdd)))

// On unmount clear all the effects.
useEffect(() => {
return () => {
activeEffects.current.forEach(cleanUp => cleanUp());
activeEffects.current.clear();
};
}, [])
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant