Teniendo el siguiente componente:
import { ChangeEvent, useCallback, useState } from 'react'; export function SearchComponent() { const [searchValue, setSearchValue] = useState<string>(''); const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => { setSearchValue(event.target.value); }, []); return ( <div> <input value={searchValue} onChange={updateSearchValue} /> </div> ); } Actualiza ese valor de estado, searchValue con el valor introducido en la entrada.
Con ese valor, la URL se actualiza así:
window.location.hash = searchValue ? `?searchBy=${searchValue}` : ''; Agrega un # adicional a la URL, antes era example.com/test , ahora es example.com/test#?searchBy=my_input pero no es un gran problema.
Lo que quiero es poder modificar directamente la entrada y almacenar ese nuevo valor en el componente, así que lo he intentado así:
const queryParams = new URLSearchParams(window.location.search); const searchBy = queryParams.get('searchBy'); Cuando se registra, queryParams es un objeto vacío mientras que searchBy es null .
¿Hay alguna forma de almacenar el valor de la URL si el usuario va a editar ese valor?
El problema es que window.location.hash = searchValue ? `?searchBy=${searchValue}` : ''; actualiza el hash de ubicación, agregando así el "#" a la URL, y no window.location.search , que es la parte queryString de la URL.
El uso window.location también es un poco antipatrón, ya que muta la ubicación y obliga a recargar la página. Es mejor usar las herramientas disponibles para usted desde react-router-dom para emitir una acción de navegación en lugar de recargar toda la aplicación.
Al usar react-router-dom@5 , deberá usar los ganchos useHistory y useLocation y acceder al valor de location.search e instanciar su propio objeto URLSearchParams . Establezca el estado inicial de searchValue desde queryString y use un useEffect para actualizar los parámetros de búsqueda y emita una redirección imperativa a la ruta actual con la cadena de consulta actualizada.
Ejemplo:
import { useLocation, useHistory } from 'react-router-dom'; export function SearchComponent() { const history = useHistory(); const { pathname, search } = useLocation(); const searchParams = React.useMemo(() => new URLSearchParams(search), [ search ]); const [searchValue, setSearchValue] = useState<string>( searchParams.get("searchBy") || "" ); useEffect(() => { searchParams.set("searchBy", searchValue); history.replace({ pathname, search: searchParams.toString(), }); }, [history, pathname, searchParams, searchValue]); const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => { setSearchValue(event.target.value); }, []); return ( <div> <input value={searchValue} onChange={updateSearchValue} /> </div> ); }