Skip to content

FeedbackSet and example #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: demo-base-1
Choose a base branch
from
Open

FeedbackSet and example #4

wants to merge 1 commit into from

Conversation

markotron
Copy link
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
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