Skip to content

Instantly share code, notes, and snippets.

@solomon-gumball
Last active June 12, 2022 09:48
Show Gist options
  • Save solomon-gumball/155d32d3151642cbc90b07ee92914ebd to your computer and use it in GitHub Desktop.
Save solomon-gumball/155d32d3151642cbc90b07ee92914ebd to your computer and use it in GitHub Desktop.
declare function searchForMovies(query?: string): Promise<Movie[]>
declare function MovieList(props: { movies: Movie[] }): JSX.Element
declare function LoadingIndicator(props: { loadingSince: Date }): JSX.Element
declare function ErrorMessageUI(props: { error: Error }): JSX.Element
type Movie = { title: string, id: string }
type ViewState = (
{ status: 'loading', loadingSince: Date } |
{ status: 'done', searchResults: Movie[] } |
{ status: 'error', error: Error }
)
export default function MovieSearch() {
const [searchTerm, setSearchTerm] = useState<string>('')
const [viewState, setViewState] = useState<ViewState>({ status: 'loading', loadingSince: new Date() })
useEffect(() => {
setViewState({ status: 'loading', loadingSince: new Date() })
searchForMovies(searchTerm).then(movies => {
setViewState({ status: 'done', searchResults: movies })
}).catch((error: Error) => {
setViewState({ status: 'error', error: error })
})
}, [searchTerm])
return (
<div>
<input value={searchTerm} onChange={e => setSearchTerm(e.target.value)} />
{viewState.status === 'loading' && <LoadingIndicator loadingSince={viewState.loadingSince} />}
{viewState.status === 'done' && <MovieList movies={viewState.searchResults} />}
{viewState.status === 'error' && <ErrorMessageUI error={viewState.error} />}
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment