fix(#548): moved store higher to share search results btw pages (#216)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 9b37149cb4
commit 0b0d6d4644
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 46
      src/features/App/AuthenticatedApp.tsx
  2. 12
      src/features/ExtendedSearchPage/index.tsx
  3. 9
      src/features/ExtendedSearchPage/store/hooks/index.tsx
  4. 81
      src/features/Search/hooks/index.tsx
  5. 10
      src/features/Search/index.tsx

@ -15,7 +15,7 @@ import { TeamPage } from 'features/TeamPage'
import { MatchPage } from 'features/MatchPage' import { MatchPage } from 'features/MatchPage'
import { PlayerPage } from 'features/PlayerPage' import { PlayerPage } from 'features/PlayerPage'
import { TournamentPage } from 'features/TournamentPage' import { TournamentPage } from 'features/TournamentPage'
import { ExtendedSearchPage } from 'features/ExtendedSearchPage' import { ExtendedSearchStore, ExtendedSearchPage } from 'features/ExtendedSearchPage'
import { LanguageSelect } from 'features/LanguageSelect' import { LanguageSelect } from 'features/LanguageSelect'
import { UserAccount } from 'features/UserAccount' import { UserAccount } from 'features/UserAccount'
import { ScoreStore, ToggleScore } from 'features/ToggleScore' import { ScoreStore, ToggleScore } from 'features/ToggleScore'
@ -45,29 +45,31 @@ export const AuthenticatedApp = () => {
<UserAccountForm /> <UserAccountForm />
</Route> </Route>
<UserFavoritesStore> <UserFavoritesStore>
<MainWrapper> <ExtendedSearchStore>
{!isMobile && <UserFavorites />} <MainWrapper>
<Route exact path={PAGES.home}> {!isMobile && <UserFavorites />}
<HomePage /> <Route exact path={PAGES.home}>
</Route> <HomePage />
</Route>
<Route path={`/:sportName${PAGES.tournament}/:pageId`}> <Route path={`/:sportName${PAGES.tournament}/:pageId`}>
<TournamentPage /> <TournamentPage />
</Route> </Route>
<Route path={`/:sportName${PAGES.team}/:pageId`}> <Route path={`/:sportName${PAGES.team}/:pageId`}>
<TeamPage /> <TeamPage />
</Route> </Route>
<Route path={`/:sportName${PAGES.player}/:pageId`}> <Route path={`/:sportName${PAGES.player}/:pageId`}>
<PlayerPage /> <PlayerPage />
</Route> </Route>
<Route path={`/:sportName${PAGES.match}/:pageId`}> <Route path={`/:sportName${PAGES.match}/:pageId`}>
<MatchPage /> <MatchPage />
</Route> </Route>
<Route path={PAGES.extendedSearch}> <Route path={PAGES.extendedSearch}>
<ExtendedSearchPage /> <ExtendedSearchPage />
</Route> </Route>
</MainWrapper> </MainWrapper>
</ExtendedSearchStore>
</UserFavoritesStore> </UserFavoritesStore>
<Redirect to={PAGES.home} /> <Redirect to={PAGES.home} />
</Switch> </Switch>

@ -7,11 +7,13 @@ import { useMediaQuery } from 'features/MediaQuery'
import { MobileHeader } from './components/MobileHeader' import { MobileHeader } from './components/MobileHeader'
import { DesktopHeader } from './components/DesktopHeader' import { DesktopHeader } from './components/DesktopHeader'
import { Results } from './components/Results' import { Results } from './components/Results'
import { ExtendedSearchStore, useExtendedSearchStore } from './store' import { useExtendedSearchStore } from './store'
import { Main } from './styled' import { Main } from './styled'
const ExtendedSearch = () => { export { ExtendedSearchStore } from './store'
export const ExtendedSearchPage = () => {
const { searchItems } = useExtendedSearchStore() const { searchItems } = useExtendedSearchStore()
const isMobile = useMediaQuery({ query: devices.tablet }) const isMobile = useMediaQuery({ query: devices.tablet })
return ( return (
@ -27,9 +29,3 @@ const ExtendedSearch = () => {
</Fragment> </Fragment>
) )
} }
export const ExtendedSearchPage = () => (
<ExtendedSearchStore>
<ExtendedSearch />
</ExtendedSearchStore>
)

@ -72,6 +72,14 @@ export const useExtendedSearch = () => {
cancelSearch, cancelSearch,
]) ])
const reset = useCallback(() => {
setSearchItems(initialState)
setQuery('')
setSelectedSport(null)
setSelectedGender(null)
setSelectedProfile(null)
}, [])
return { return {
isFetching, isFetching,
onGenderChange, onGenderChange,
@ -79,6 +87,7 @@ export const useExtendedSearch = () => {
onQueryChange, onQueryChange,
onSportChange: setSelectedSport, onSportChange: setSelectedSport,
query, query,
reset,
searchItems, searchItems,
selectedGender, selectedGender,
selectedProfile, selectedProfile,

@ -1,27 +1,18 @@
import type { FormEvent, ChangeEvent } from 'react' import type { FormEvent } from 'react'
import { import { useCallback, useEffect } from 'react'
useState,
useRef,
useCallback,
} from 'react'
import trim from 'lodash/trim' import { useToggle } from 'hooks'
import debounce from 'lodash/debounce'
import size from 'lodash/size'
import type { SearchItems } from 'requests' import { useExtendedSearchStore } from 'features/ExtendedSearchPage/store'
import { getSearchItems } from 'requests'
import {
useRequest,
useToggle,
} from 'hooks'
import { SEARCH_DELAY, MIN_CHARACTERS_LENGTH } from '../config'
import { normalizeItems } from '../helpers'
export const useSearch = () => { export const useSearch = () => {
const [searchItems, setSearchItems] = useState<SearchItems>({}) const {
const abortControllerRef = useRef<AbortController | null>(null) isFetching,
onQueryChange,
query,
reset,
searchItems,
} = useExtendedSearchStore()
const { const {
close, close,
@ -29,58 +20,22 @@ export const useSearch = () => {
open, open,
} = useToggle() } = useToggle()
const {
isFetching,
request: searchItemsRequest,
} = useRequest(getSearchItems)
const fetchSearchItems = useCallback(debounce((searchString: string) => {
const abortController = new window.AbortController()
abortControllerRef.current = abortController
searchItemsRequest(searchString, abortController.signal).then((data) => {
setSearchItems(data)
abortControllerRef.current = null
})
}, SEARCH_DELAY), [])
const cancelRequest = useCallback(() => {
const abortController = abortControllerRef.current
if (abortController) {
abortController.abort()
abortControllerRef.current = null
}
}, [])
const onChange = useCallback(({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
const trimmedValue = trim(value)
if (size(trimmedValue) >= MIN_CHARACTERS_LENGTH) {
cancelRequest()
setSearchItems({})
fetchSearchItems(trimmedValue)
open()
} else {
close()
}
}, [
cancelRequest,
close,
fetchSearchItems,
open,
])
const onSubmit = useCallback((e: FormEvent<HTMLFormElement>) => { const onSubmit = useCallback((e: FormEvent<HTMLFormElement>) => {
e.preventDefault() e.preventDefault()
}, []) }, [])
useEffect(() => {
reset()
}, [reset])
return { return {
close, close,
isFetching, isFetching,
normalizedItems: normalizeItems(searchItems), onChange: onQueryChange,
onChange,
onFocus: open, onFocus: open,
onSubmit, onSubmit,
query,
searchItems,
showResults: isOpen, showResults: isOpen,
} }
} }

@ -26,14 +26,15 @@ export const Search = () => {
const { const {
close, close,
isFetching, isFetching,
normalizedItems: { onChange,
onFocus,
onSubmit,
query,
searchItems: {
players, players,
teams, teams,
tournaments, tournaments,
}, },
onChange,
onFocus,
onSubmit,
showResults, showResults,
} = useSearch() } = useSearch()
@ -45,6 +46,7 @@ export const Search = () => {
<Input <Input
autoComplete='off' autoComplete='off'
type='search' type='search'
value={query}
onChange={onChange} onChange={onChange}
onFocus={onFocus} onFocus={onFocus}
/> />

Loading…
Cancel
Save