Created
March 30, 2022 22:36
-
-
Save cephalization/ffbf0e353dd77ad02c176163105afb52 to your computer and use it in GitHub Desktop.
Incorrect useTransition usage
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 characters
| import React, { useCallback, useEffect, useState, useTransition } from 'react'; | |
| import { useAppDispatch, useAppSelector } from '~/hooks'; | |
| import { libraryActions } from '~/store/slices/library/library'; | |
| import { librarySelectors } from '~/store/slices/library/selectors'; | |
| // Search input | |
| // Dispatches redux thunk when text input changes | |
| export function TrackSearch() { | |
| const dispatch = useAppDispatch(); | |
| const libraryFilter = useAppSelector(librarySelectors.selectLibraryFilter); | |
| const [localFilter, setLocalFilter] = useState(libraryFilter); | |
| const [_, startTransition] = useTransition() | |
| // synchronize local input state with redux when redux changes outside of this component | |
| useEffect(() => { | |
| if (localFilter !== libraryFilter) { | |
| setLocalFilter(libraryFilter); | |
| } | |
| }, [libraryFilter]); | |
| // set the local input state onchange | |
| const onChange = useCallback( | |
| (e) => { | |
| const value = e.target.value; | |
| setLocalFilter(value); | |
| }, | |
| [setLocalFilter], | |
| ); | |
| // dispatch the local input state to a redux thunk that will fetch search results | |
| // NOTE: this does not work the way that I immediately thought it would | |
| // transitions help with react state updates, not external state updates | |
| // this process cannot be interrupted by react | |
| startTransition(() => { | |
| dispatch(libraryActions.setLibraryFilter({ localFilter })); | |
| }) | |
| return ( | |
| <div> | |
| <form action="#" method="GET"> | |
| <input | |
| name="search_field" | |
| placeholder="Search your library" | |
| type="search" | |
| value={localFilter} | |
| onChange={onChange} | |
| /> | |
| </form> | |
| </div> | |
| ); | |
| } |
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 characters
| import { SearchIcon } from '@heroicons/react/outline'; | |
| import debounce from 'lodash.debounce'; | |
| import React, { useCallback, useEffect, useState } from 'react'; | |
| import { useAppDispatch, useAppSelector } from '~/hooks'; | |
| import { libraryActions } from '~/store/slices/library/library'; | |
| import { librarySelectors } from '~/store/slices/library/selectors'; | |
| export function TrackSearch() { | |
| const dispatch = useAppDispatch(); | |
| const libraryFilter = useAppSelector(librarySelectors.selectLibraryFilter); | |
| const [localFilter, setLocalFilter] = useState(libraryFilter); | |
| const dSetFilter = useCallback( | |
| debounce((filter: string) => { | |
| dispatch(libraryActions.setLibraryFilter({ filter })); | |
| }, 300), | |
| [], | |
| ); | |
| const onChange = useCallback( | |
| (e) => { | |
| const value = e.target.value; | |
| setLocalFilter(value); | |
| dSetFilter(value); | |
| }, | |
| [dSetFilter, setLocalFilter], | |
| ); | |
| useEffect(() => { | |
| if (localFilter !== libraryFilter) { | |
| setLocalFilter(libraryFilter); | |
| } | |
| }, [libraryFilter]); | |
| return ( | |
| <div className="flex-1 flex"> | |
| <form className="w-full flex md:ml-0" action="#" method="GET"> | |
| <label htmlFor="search_field" className="sr-only"> | |
| Search library | |
| </label> | |
| <div className="relative w-full text-gray-400 focus-within:text-gray-600"> | |
| <div className="absolute inset-y-0 left-0 flex items-center pointer-events-none"> | |
| <SearchIcon className="h-5 w-5" /> | |
| </div> | |
| <input | |
| id="search_field" | |
| name="search_field" | |
| className="block w-full h-full pl-8 pr-3 py-2 border-transparent text-gray-900 placeholder-gray-500 focus:outline-none focus:ring-0 focus:border-transparent focus:placeholder-gray-400 sm:text-sm" | |
| placeholder="Search your library" | |
| type="search" | |
| value={localFilter} | |
| onChange={onChange} | |
| />{' '} | |
| </div> | |
| </form> | |
| </div> | |
| ); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The first file is a stripped down example of what I thought I could do with useTransition after reading the changelog.
On reflection and re-reading the docs I realize that this is incorrect, and debounce is still the correct solution.
Posting for posterity.