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.

Revisions

  1. chrisdhanaraj revised this gist Feb 17, 2020. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions useSearch.tsx
    Original file line number Diff line number Diff line change
    @@ -59,6 +59,10 @@ function createReducer({
    });
    });
    }

    // ---------------------------
    // ACTIONS
    // ---------------------------

    if (
    state.status === 'initial' ||
  2. chrisdhanaraj revised this gist Feb 17, 2020. 1 changed file with 11 additions and 33 deletions.
    44 changes: 11 additions & 33 deletions useSearch.tsx
    Original file line number Diff line number Diff line change
    @@ -6,43 +6,28 @@ import useReducerWithSideEffects, {
    ReducerReturn
    } from 'use-reducer-with-side-effects';
    import { useCallback, useEffect, useContext } from 'react';
    import { SearchContext, SelectedItems } from '../index';
    import {
    UseSearchState,
    SearchAction,
    CreateSearchReducer,
    UseSearchDispatch,
    UseSearchParameters,
    UseSearchReturn
    } from './types';
    import { SearchVariable } from '../search-client/types';

    const initialStateArgs = {
    status: 'initial',
    searchResults: null
    };

    function createReducer<MapleQuery>({
    function createReducer({
    query,
    page,
    perPage,
    ranking,
    client
    }: CreateSearchReducer): Reducer<UseSearchState<MapleQuery>, SearchAction<MapleQuery>> {
    }) {
    return function reducer(
    state: UseSearchState<MapleQuery>,
    action: SearchAction<MapleQuery>
    ): ReducerReturn<UseSearchState<MapleQuery>, SearchAction<MapleQuery>> | symbol {
    state,
    action
    ) {
    // ---------------------------
    // SIDE EFFECTS
    // ---------------------------

    interface QuerySearchParameters {
    selectedItems: SelectedItems;
    dispatch: UseSearchDispatch<MapleQuery>;
    }

    function _querySearch({ selectedItems, dispatch }: QuerySearchParameters): void {
    function _querySearch({ selectedItems, dispatch }) {
    const variables: SearchVariable = {
    page: {
    type: 'Int!',
    @@ -94,12 +79,12 @@ function createReducer<MapleQuery>({
    }

    if (action.selectedItemsState.selectedItems.size > 0) {
    return UpdateWithSideEffect<UseSearchState<MapleQuery>, SearchAction<MapleQuery>>(
    return UpdateWithSideEffect(
    {
    ...state,
    status: 'loading'
    },
    (_, dispatch: UseSearchDispatch<MapleQuery>) => {
    (_, dispatch: UseSearchDispatch) => {
    _querySearch({
    selectedItems: action.selectedItemsState.selectedItems,
    dispatch
    @@ -124,21 +109,21 @@ function createReducer<MapleQuery>({
    };
    }

    export function useSearch<MapleQuery>({
    export function useSearch({
    query,
    selectedDispatch,
    page = 1,
    perPage = 10,
    ranking
    }: UseSearchParameters): UseSearchReturn<MapleQuery> {
    }) {
    const searchContext = useContext(SearchContext);

    if (searchContext === undefined) {
    throw new Error('No SearchContext available');
    }

    const reducer = useCallback(
    createReducer<MapleQuery>({
    createReducer({
    query,
    page,
    perPage,
    @@ -150,13 +135,6 @@ export function useSearch<MapleQuery>({

    const [state, dispatch] = useReducerWithSideEffects(reducer, initialStateArgs);

    useEffect(() => {
    selectedDispatch({
    type: 'REGISTER_DISPATCHER',
    dispatcher: dispatch
    });
    }, [selectedDispatch, dispatch]);

    return {
    state,
    dispatch
  3. chrisdhanaraj created this gist Feb 17, 2020.
    164 changes: 164 additions & 0 deletions useSearch.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,164 @@
    import useReducerWithSideEffects, {
    NoUpdate,
    Update,
    UpdateWithSideEffect,
    Reducer,
    ReducerReturn
    } from 'use-reducer-with-side-effects';
    import { useCallback, useEffect, useContext } from 'react';
    import { SearchContext, SelectedItems } from '../index';
    import {
    UseSearchState,
    SearchAction,
    CreateSearchReducer,
    UseSearchDispatch,
    UseSearchParameters,
    UseSearchReturn
    } from './types';
    import { SearchVariable } from '../search-client/types';

    const initialStateArgs = {
    status: 'initial',
    searchResults: null
    };

    function createReducer<MapleQuery>({
    query,
    page,
    perPage,
    ranking,
    client
    }: CreateSearchReducer): Reducer<UseSearchState<MapleQuery>, SearchAction<MapleQuery>> {
    return function reducer(
    state: UseSearchState<MapleQuery>,
    action: SearchAction<MapleQuery>
    ): ReducerReturn<UseSearchState<MapleQuery>, SearchAction<MapleQuery>> | symbol {
    // ---------------------------
    // SIDE EFFECTS
    // ---------------------------

    interface QuerySearchParameters {
    selectedItems: SelectedItems;
    dispatch: UseSearchDispatch<MapleQuery>;
    }

    function _querySearch({ selectedItems, dispatch }: QuerySearchParameters): void {
    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
    });
    });
    }

    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<UseSearchState<MapleQuery>, SearchAction<MapleQuery>>(
    {
    ...state,
    status: 'loading'
    },
    (_, dispatch: UseSearchDispatch<MapleQuery>) => {
    _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<MapleQuery>({
    query,
    selectedDispatch,
    page = 1,
    perPage = 10,
    ranking
    }: UseSearchParameters): UseSearchReturn<MapleQuery> {
    const searchContext = useContext(SearchContext);

    if (searchContext === undefined) {
    throw new Error('No SearchContext available');
    }

    const reducer = useCallback(
    createReducer<MapleQuery>({
    query,
    page,
    perPage,
    ranking,
    client: searchContext.client
    }),
    [query, page, perPage, ranking]
    );

    const [state, dispatch] = useReducerWithSideEffects(reducer, initialStateArgs);

    useEffect(() => {
    selectedDispatch({
    type: 'REGISTER_DISPATCHER',
    dispatcher: dispatch
    });
    }, [selectedDispatch, dispatch]);

    return {
    state,
    dispatch
    };
    }