Skip to content

Instantly share code, notes, and snippets.

@chrisdhanaraj
Last active February 17, 2020 23:28
Show Gist options
  • Save chrisdhanaraj/cccd1a5cef4da4150c2c53f7ba8dd00f to your computer and use it in GitHub Desktop.
Save chrisdhanaraj/cccd1a5cef4da4150c2c53f7ba8dd00f to your computer and use it in GitHub Desktop.
Use Redicer with Side Effects example
import useReducerWithSideEffects, {
NoUpdate,
Update,
UpdateWithSideEffect,
Reducer,
ReducerReturn
} from 'use-reducer-with-side-effects';
import { useCallback, useEffect, useContext } from 'react';
const initialStateArgs = {
status: 'initial',
searchResults: null
};
function createReducer({
query,
page,
perPage,
ranking,
client
}) {
return function reducer(
state,
action
) {
// ---------------------------
// SIDE EFFECTS
// ---------------------------
function _querySearch({ selectedItems, dispatch }) {
const variables: SearchVariable = {
page: {
type: 'Int!',
value: page
},
perPage: {
type: 'Int!',
value: perPage
}
};
if (ranking !== undefined) {
variables['ranking'] = {
type: '[String]',
value: ranking
};
}
client
.fetchFromMaple<MapleQuery>({
selectedItems,
query,
variables
})
.then(results => {
dispatch({
type: 'SUCCESS',
searchResults: results.data
});
});
}
// ---------------------------
// ACTIONS
// ---------------------------
if (
state.status === 'initial' ||
state.status === 'loading' ||
state.status === 'success' ||
state.status === 'failure'
) {
if (
action.type === 'PARENT_STATE_CHANGED' ||
action.type === 'DISPATCH_INITIALIZED' ||
action.type === 'FETCH_SEARCH'
) {
if (action.selectedItemsState.selectedItems.size === 0) {
return Update({
status: 'initial',
searchResults: null
});
}
if (action.selectedItemsState.selectedItems.size > 0) {
return UpdateWithSideEffect(
{
...state,
status: 'loading'
},
(_, dispatch: UseSearchDispatch) => {
_querySearch({
selectedItems: action.selectedItemsState.selectedItems,
dispatch
});
}
);
}
return NoUpdate();
}
if (action.type === 'SUCCESS') {
return Update({
...state,
searchResults: action.searchResults,
status: 'success'
});
}
}
return NoUpdate();
};
}
export function useSearch({
query,
selectedDispatch,
page = 1,
perPage = 10,
ranking
}) {
const searchContext = useContext(SearchContext);
if (searchContext === undefined) {
throw new Error('No SearchContext available');
}
const reducer = useCallback(
createReducer({
query,
page,
perPage,
ranking,
client: searchContext.client
}),
[query, page, perPage, ranking]
);
const [state, dispatch] = useReducerWithSideEffects(reducer, initialStateArgs);
return {
state,
dispatch
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment