Tengo una aplicación NextJS donde estoy creando una página de resultados de búsqueda basada en un parámetro de consulta que se pasa. Estoy usando el siguiente / enrutador para recoger la cadena de consulta. La primera vez que se carga la página después de la compilación, se selecciona la cadena de consulta y la llamada a la API es exitosa y devuelve resultados. Cada intento posterior, ya sea en una actualización F5, recargando la página a través del botón de recarga o accediendo a la página nuevamente, la llamada a la API no da resultados porque la cadena de consulta no está definida.
la URL: http://localhost:3000/search?search=blah
import { useRouter } from "next/router"; import React, { useEffect, useState } from 'react'; import axios from 'axios' export default function SearchResults1(props) { const { query } = useRouter(); const [searchResults, setSearchResults] = useState({}) const [ getQuery, setQuery] = useState({}) useEffect(() => { function fetchData(){ setQuery(query.search) console.log(getQuery) if (getQuery) { axios.get(`http://localhost:3001/search/${getQuery}`) .then((response) => { setSearchResults(response.data) }) .catch((error) => { console.warn(error) }) } } fetchData() },[getQuery, setQuery])Intenté agregar getQuery y setQuery en el gancho useEffect para que se active cuando haya cambios, pero sigo sin definir cada vez que cargo la página por segunda vez.
También intenté eliminar getQuery y setQuery y lo intenté sin usar el estado, pero sigo obteniendo el mismo resultado si llamo a query.search directamente: la primera vez que funciona, posteriormente no lo hace.
Me di cuenta de que si llamé a {query.search} en el HTML de retorno, siempre se muestra, por lo que creo que tiene algo que ver con la llamada a la API y no esperar a que se complete la consulta.
return ( <div>{query.search}</div> <!--this always works and shows the correct value--> )¿Alguna idea o sugerencia sobre cómo puedo lograr resultados consistentes y devolver siempre los parámetros de consulta para poder hacer una buena llamada a la API? Estoy bastante seguro de que me estoy perdiendo algo obvio.
En lugar de analizarlo directamente con useRouter() , intente que el enrutador esté listo y acceda a él una vez que esté listo en useEffect .
import { useRouter } from "next/router"; import React, { useEffect, useState } from 'react'; import axios from 'axios' export default function SearchResults1(props) { const router = useRouter(); const [searchResults, setSearchResults] = useState({}) //const query = router.query; <-- or use this. The point is to access router.isReady in useEffect useEffect(() => { if (!router.isReady) return; // <-- only use the query when it is ready. function fetchData(){ axios.get(`http://localhost:3001/search/${router.query.search}`) .then((response) => { setSearchResults(response.data) }) .catch((error) => { console.warn(error) }) } fetchData() },[router.isReady]) // <-- use this router.isReady De acuerdo con Next.js, It will be an empty object during prerendering if the page doesn't have data fetching requirements.
https://nextjs.org/docs/api-reference/next/router
De esta manera, podemos asegurarnos de que la información del enrutador esté lista para usar cuando acceda a ella.