Last active
November 28, 2020 18:25
-
-
Save GriffinSauce/0451d328511b4e82469f4e9f688e5118 to your computer and use it in GitHub Desktop.
Revisions
-
GriffinSauce revised this gist
Feb 17, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ const SHOW_LOADING_AFTER_MS = 300; export const useAlgoliaSearch = ({ initialSearchState = {}, initialResults = null, // For SSR onResults, // Eg. to track to analytics when results are shown }) => { if (!initialSearchState.index) throw new Error('initialSearchState with index is required'); -
GriffinSauce revised this gist
Feb 15, 2020 . 1 changed file with 1 addition and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -45,10 +45,7 @@ export const useAlgoliaSearch = ({ // Get results try { const searchIndex = algoliaClient.initIndex(index); const res = await searchIndex.search(searchOptions); setResults(res); clearTimeout(loadingTimeout); setLoading(false); -
GriffinSauce revised this gist
Feb 15, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ const SHOW_LOADING_AFTER_MS = 300; */ export const useAlgoliaSearch = ({ initialSearchState = {}, initialResults = null, // For SSR onResults, }) => { if (!initialSearchState.index) -
GriffinSauce created this gist
Feb 15, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,113 @@ import React, { useState, useEffect, useContext, useRef } from 'react'; import algoliasearch from 'algoliasearch/lite'; const algoliaClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_API_KEY); const SHOW_LOADING_AFTER_MS = 300; /** * Initialize a search * * @example: * const { searchState, setSearchState, results, isLoading } = useAlgoliaSearch(); * const onSubmit = (query) => { * setSearchState(current => ({ ...current, query })); * } */ export const useAlgoliaSearch = ({ initialSearchState = {}, initialResults = null, onResults, }) => { if (!initialSearchState.index) throw new Error('initialSearchState with index is required'); const skip = useRef(!!initialResults); // The search query and options const [searchState, setSearchState] = useState({ ...initialSearchState, context: initialSearchState.context || {}, // Put additional custom data in searchState.context - the search lib will keep it in state and won't touch it getRankingInfo: true, }); const [results, setResults] = useState(initialResults); const [isLoading, setLoading] = useState(false); useEffect( () => { const { index, context, ...searchOptions } = searchState; // Algolia errors on unknown parameters so filter them out const getResults = async () => { // Show loading after a while to prevent jumpyness const loadingTimeout = setTimeout( () => setLoading(true), SHOW_LOADING_AFTER_MS, ); // Get results try { const searchIndex = algoliaClient.initIndex(index); const res = await searchIndex.search({ ...searchOptions, aroundPrecision: precisionFromRadius(searchOptions.aroundRadius), // Dynamically set geo buckets size that makes sense based on radius }); setResults(res); clearTimeout(loadingTimeout); setLoading(false); if (onResults) onResults({ searchState, results: res }); } catch (error) { if (error.message.toLowerCase().includes('unknown parameter')) { error.message = `${ error.message } - if you want to add custom (non-Algolia) parameters, use searchState.context`; } console.error(`useAlgoliaSearch error: ${error.message}`); // Send error to sentry or whatever here clearTimeout(loadingTimeout); setLoading(false); } }; // If initialResults is provided we can skip once if (skip.current) { skip.current = false; return; } getResults(); }, [searchState, onResults], ); return { searchState, setSearchState, results, isLoading, }; }; /** * Context to access/mutate search down the component tree * * @example - Create the context: * const searchContext = useAlgoliaSearch(); * retusn ( * <SearchContext.Provider value={searchContext}> * <SearchBox /> * </SearchContext.Provider> * ); */ export const SearchContext = React.createContext(); /** * Hook to easily grab search props from context * Returns whatever is passed into SearchContext.Provider */ export const useSearchContext = () => { const searchContext = useContext(SearchContext); if (!searchContext) throw new Error( 'No search context found, make sure the component is wrapped with a <SearchContext.Provider>', ); return searchContext; };