Skip to content

Instantly share code, notes, and snippets.

@ruswerner
Created October 27, 2020 20:16
Show Gist options
  • Select an option

  • Save ruswerner/a0563ae0f5c00e14881ace047941c236 to your computer and use it in GitHub Desktop.

Select an option

Save ruswerner/a0563ae0f5c00e14881ace047941c236 to your computer and use it in GitHub Desktop.
import React, {createContext, FC, ReactNode, useCallback, useMemo, useReducer} from 'react';
import {usePersistentRef} from '@shared/util/hooks';
export const CardListProviderStateContext = createContext(null);
export const CardListProviderActionsContext = createContext(null);
type Card = any;
interface Query {
channelId: number;
sortBy: any[];
tagFieldName: string;
tagId: string;
}
interface ListCacheItem {
cardIds: string[];
loading: boolean;
hasMore: boolean;
query: Query;
}
interface State {
listCache: ListCacheItem[];
cardCache: {[key: string]: Card};
}
const reducer = (state: State, action: any): State => {
let newState: State = null;
// create new state using action.type
return newState;
};
const init = (): State => {
return {
listCache: [],
cardCache: {}
};
};
export const CardListProvider: FC<{children: ReactNode}> = ({children}) => {
const [state, dispatch] = useReducer(reducer, null, init);
const stateRef = usePersistentRef(state);
const onAdd = useCallback((card: Card) => dispatch({type: 'onAdd', card}), [dispatch]);
const onUpdate = useCallback(
(card: Card, skip: boolean) => dispatch({type: 'onUpdate', card, skip}),
[dispatch]
);
const onRemove = useCallback((card: Card) => dispatch({type: 'onRemove', card}), [dispatch]);
const onFetchMore = useCallback(
async (query: any) => {
dispatch({type: 'onFetchMoreStart', query}); // sets loading=true
// need offset here from state
const offset = stateRef.current.offset;
const data = await apolloClient.query(offset);
dispatch({type: 'onFetchMoreFinish', query, data}); // sets data & loading=false
},
[dispatch, stateRef]
);
const actions = useMemo(
() => ({
onAdd,
onUpdate,
onRemove,
onFetchMore
}),
[onAdd, onUpdate, onRemove, onFetchMore]
);
return (
<CardListProviderActionsContext.Provider value={actions}>
<CardListProviderStateContext.Provider value={state}>
{useMemo(() => children, [children])}
</CardListProviderStateContext.Provider>
</CardListProviderActionsContext.Provider>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment