Con el enrutador de reacción, he hecho esto para actualizar la URL:
this.props.history.push({
pathname: `/product/${this.props.product.id}`,
});
Sin embargo, esto provoca un cambio de renderizado/navegación. ¿Hay alguna manera de actualizar la URL sin hacer eso?
Mi caso de uso es que tengo una lista de productos y cuando hago clic en uno, muestro un Modal y quiero actualizar la URL a algo como ejemplo.com/producto/1 para que el enlace se pueda compartir.
No pude encontrar una solución usando React Router, pero pude lograr esto usando la interfaz de historial del navegador llamando:
window.history.replaceState(null, "New Page Title", "/pathname/goes/here")
Puedes aprender más sobre .replaceState
aquí.
Reaccionar del enrutador history.replace
no siempre funcionará
Reaccionar del enrutador history.replace
El método puede activar o no una nueva representación dependiendo de la configuración de la ruta de su aplicación (por ejemplo, tiene un catch-all /*
ruta). No impide un renderizado por definición.
-
Tenga en cuenta que este cambio podría pasar por alto el conocimiento de React Router de la ruta actual si se vuelve a modificar más tarde. Por ejemplo, si agrega 1 subruta usando este método y luego usa RR para navegar hacia arriba 1 nivel, saltará visualmente 2 porque RR aún cree que la ubicación no tiene la subruta adjunta.
– Toro Magnus
26 de enero de 2021 a las 10:13
-
Tuve exactamente el mismo problema que el OP y lo resolví usando su enfoque. ¡Muchas gracias! @MagnusBull para el historial del navegador, simplemente uso
window.history.pushState(stringify(currentParams), "");
y eso parece funcionar, aunque no he encontrado el problema de la ruta secundaria del que hablaste– Sangeet Agarwal
15 de marzo de 2021 a las 17:48
-
@ usr28765526 Mi punto es que si usa React Router para manejar la navegación, entonces usa la API del navegador
replaceState
puede considerarse un “hackeo” y RR no sabrá que la ruta cambió. Si intenta usar React Router’slocation
una vez modificada la URL, operará sobre la versión de la URL que conoce: La anterior al cambio. Esto puede ser impredecible y confuso.– Toro Magnus
16 de marzo de 2021 a las 18:37
-
¡Muy útil, gracias! No sabía que history.replace podría causar re-renderizaciones
– Katie Fedoseeva
26/09/2022 a las 23:50
AngelSalazar
reemplazar anulará la URL
this.props.history.replace({ pathname: `/product/${this.props.product.id}`})
-
Eso definitivamente todavía hace que el enrutador actúe, y luego hay una pantalla en blanco (supongo que no puede encontrar una ruta)
– peculiaridades extrañas
18 de julio de 2019 a las 20:15
-
realmente, reemplazar solo debe anular la URL
– Ángel Salazar
18 de julio de 2019 a las 20:22
-
Encontré esto que funciona: window.history.replaceState(null, null,
/product/${this.props.product.id}
);– peculiaridades extrañas
18 de julio de 2019 a las 20:23
-
react-router replace debería comportarse como replaceState. Puedo confirmar que replace no activa un renderizado, consulte esta pequeña demostración jsbin.com/jinazirowa/edit?html,js,salida
– Ángel Salazar
18 de julio de 2019 a las 20:26
-
Esto debería funcionar sin actualizar/renderizar, siempre que la ruta del enrutador encapsule la nueva ruta.
– Toro Magnus
26 de enero de 2021 a las 10:09
nivek mozart
Estoy usando una buena forma de engañar a los usuarios: la URL no cambia.
Para hacer esto, solo necesitará configurar sus rutas de esta manera.
const Home="https://stackoverflow.com/";
const About="https://stackoverflow.com/";
const Contact="https://stackoverflow.com/";
Fíjate en los espacios. Todos los caracteres se contarán dentro de la cita, por lo que debería funcionar.
Routes.tsx
<Route exact path={Home} component={Home} />
<Route exact path={About} component={About} />
<Route exact path={Contact} component={Contact} />
dentro de tu About.tsx
y Contact.tsx
:
useEffect(() => {
window.history.replaceState(null, '', Home);
}, []);
Después de que el usuario navega a About
o Contact
páginas, se llamará al gancho y se ejecutará el código dentro de la función de devolución de llamada. Eliminará los espacios después de que el componente se renderice.
Ese debería ser un truco limpio para disfrazar la URL oculta 😂
Cuando estás dentro de un componente de reacción, el props
posee history
puedes usar eso.
Para aquellos que buscan una forma de navegar incluso cuando no están dentro de un componente de reacción, es decir, no pueden obtener el props.history
Esta es un forma de hacerlo:
En el componente donde representa el enrutador:
// outside the component
export const browserRouterRef = React.createRef();
// on render
<BrowserRouter ref={browserRouterRef}>
Entonces puedes importar browserRouterRef
en cualquier lugar y uso browserRouterRef.current.history
para cambiar la ruta incluso si no está dentro de un componente de reacción.
Todo esto está integrado en el enrutador de reacción; se llama enrutamiento dinámico
– usuario5734311
18 de julio de 2019 a las 20:06
No creo que esto sea posible actualmente en react-router v6, hay un problema abierto: github.com/remix-run/react-router/issues/8908
– austin espacial
28 de julio de 2022 a las 19:13