Tengo problemas para cambiar la vista al reaccionar con el enrutamiento. Solo quiero mostrar una lista de usuarios, y al hacer clic en cada usuario, debo navegar a una página de detalles. Aquí está el enrutador:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import Users from "./components/Users";
import { Router, Route } from "react-router";
import Details from "./components/Details";
ReactDOM.render((
<BrowserRouter>
<div>
<Route path="/" component={Users} />
<Route path="/details" component={Details} />
</div>
</BrowserRouter>
), document.getElementById('app'))
Cuando utilizo la URL / detalles, mi navegador navega a esa URL, pero no cambia la vista. Cualquier otra ruta arroja 404, por lo que parece reconocer la ruta pero no actualizarla.
reactjs
react-router
MARyan87
fuente
fuente
Respuestas:
exact
Debe especificar el atributo para su indexRoute, de lo contrario/details
, aún coincidirá con la ruta uniforme/
. También intente importarRoute
desdereact-router-dom
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter, Route } from 'react-router-dom'; import Users from "./components/Users"; import Details from "./components/Details"; ReactDOM.render(( <BrowserRouter> <div> <Route exact path="/" component={Users} /> <Route path="/details" component={Details} /> </div> </BrowserRouter> ), document.getElementById('app'))
ACTUALIZAR:
Otra cosa que debe hacer es adjuntar los usuarios de su componente
withRouter
. Solo debe utilizarlowithRouter
cuando su componente no reciba elRouter props
,Esto puede suceder en los casos en que su componente es un elemento secundario anidado de un componente renderizado por el enrutador o no le ha pasado los accesorios del enrutador o cuando el componente no está vinculado al enrutador en absoluto y se representa como un componente separado de las Rutas.
En Users.js agregue
import {withRouter} from 'react-router'; ......... export default withRouter(Users)
DOCS
fuente
npm install -S 'prop-types'
y reemplazando React.PropsTypes con PropTypes. También actualice su package.json para hacer uso del último paquete, ya que otros paquetes pueden seguir usando React.PropTypes y React.createClassRoute
importado de 'react-router-dom` en lugar dereact-router
withRouter
, me ha ayudado a resolver el mismo problema antes. Házmelo saber. También he actualizado el código.Solo tienes que envolver los componentes dentro con Router .
<Route exact path="/mypath" component={withRouter(MyComponent)} />
Aquí hay un archivo App.js de muestra:
... import { BrowserRouter as Router, Route, Switch, withRouter } from "react-router-dom"; import Home from "./pages/Home"; import Profile from "./pages/Profile"; class App extends Component { render() { return ( <Router> <Switch> <Route exact path="/" component={withRouter(Home)} /> <Route exact path="/profile" component={withRouter(Profile)} /> </Switch> </Router> ); } } export default App;
Adicional
Si está utilizando el enrutador react, se llamará a componentWillReceiveProps cada vez que cambie la URL.
componentWillReceiveProps(nextProps) { var currentProductId = nextProps.match.params.productId; var nextProductId = nextProps.match.params.productId; // from the new url ... }
Nota
Alternativamente, también puede envolver el componente con Router antes de exportar, pero luego debe asegurarse de algunas otras cosas. Normalmente me salto este paso.
export default withRouter(Profile)
fuente
Tuve el mismo problema y descubrí que era porque tenía un enrutador anidado. Una vez que eliminé el enrutador anidado y simplemente puse las rutas específicas de mi componente dentro de un componente de conmutador, el problema se resolvió sin tener que usar con el enrutador o realizar cambios adicionales.
<Router> // <--Remove nested Router <Switch> <Route exact path="/workflows" component={ViewWorkflows} /> <Route path="/workflows/new" component={NewWorkflow} /> </Switch> </Router>
Yusufbek describe un problema similar. Creo que es mucho más limpio almacenar las rutas relacionadas con los componentes a nivel de vista en lugar de almacenarlas todas en un enrutador principal. En una aplicación de producción, serán demasiadas rutas para leer y depurar problemas fácilmente.
fuente
Me he enfrentado al mismo problema pero lo solucioné. He colocado la página de inicio como última. Esto funciona para mi. Como a continuación.
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter } from 'react-router-dom'; import Users from "./components/Users"; import { Router, Route } from "react-router"; import Details from "./components/Details"; ReactDOM.render(( <BrowserRouter> <div> <Route path="/details" component={Details} /> <Route path="/" component={Users} /> </div> </BrowserRouter> ), document.getElementById('app'))
fuente
exact
propiedad también lo habría resuelto.Al usar Redux y tuve problemas similares en los que la URL se actualizaba en la barra de direcciones, pero la aplicación no cargaba el componente respectivo. Pude resolver agregando withRouter a la exportación:
import { connect } from 'react-redux' import { withRouter } from 'react-router-dom' export default withRouter(connect(mapStateToProps)(MyComponentName))
fuente
Tuve un problema similar pero con una estructura diferente. Agregué un enrutador que manejará todas las rutas, usé el componente Switch para cambiar de vista. Pero en realidad no fue así. Solo la URL cambió, pero no la vista. La razón de esto fue el componente Link utilizado dentro del componente SideBar que estaba fuera del componente Router. (Sí, he exportado SideBar con "withRouter", no funcionó). Entonces, la solución fue mover mi componente SideBar que contiene todos los componentes Link a mi enrutador.
El problema está en mis enlazadores, están fuera de mi enrutador
<div className="_wrapper"> <SideBar /> // Holds my all linkers <Router> <Switch> <Route path="/" component={Home} /> <Route path="/users" component={Users} /> </Switch> </Router> </div>
La solución fue mover mis enlazadores a mi enrutador
<div className="_wrapper"> <Router> <SideBar /> // Holds my all linkers <Switch> <Route path="/" component={Home} /> <Route path="/users" component={Users} /> </Switch> </Router> </div>
fuente
En mi caso, había anidado por error dos
BrowserRouter
s.fuente
BrowserRouter no puede mantener el historial en su caso. Utilice "Enrutador" en su lugar. El uso de este con un historial personalizado como accesorios puede ayudar a resolver su problema.
import {Router, Route, Switch, withRouter } from "react-router-dom"; import Home from "./pages/Home"; import Profile from "./pages/Profile"; import {createBrowserHistory} from 'history'; export const customHistory = createBrowserHistory(); //This maintains custom history class App extends Component { render() { return ( <Router history={customHistory}> <Switch> <Route exact path="/" component={Home} /> <Route exact path="/profile" component={Profile} /> </Switch> </Router> ); } } export default App;
Luego, en sus componentes, importe customHistory desde 'App' y utilícelo para navegar.
customHistory.push('/pathname');
¡Espero que esto ayude! :)
fuente
exact
atributo cuando lo usaSwitch
Debe agregar exacto a la ruta del índice y, en lugar de incluir esos componentes de ruta por div, use Cambiar de react-router-dom para cambiar entre las rutas.
import React from "react"; import ReactDOM from "react-dom"; import { Route, Switch } from 'react-router-dom'; import Users from "./components/Users"; import Details from "./components/Details"; ReactDOM.render(( <div> <Switch> <Route path="/" component={Users} exact/> <Route path="/details" component={Details} /> </Switch> </div> ), document.getElementById('app'))
fuente
Tuve un problema similar con React Router versión 4:
Al hacer clic en el
<Link />
componente, la URL cambiaría pero las vistas no.Una de las vistas estaba usando en
PureComponent
lugar deComponent
(importada dereact
) y esa fue la causa.Mediante la sustitución de todos los componentes de la ruta dictada que estaban utilizando
PureComponent
aComponent
, se resolvió mi problema.(Fuente de resolución: https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785 )
fuente
Hmm, no hay ningún INTERRUPTOR para cambiar de vista.
así es como uso el enrutador para cambiar de la página de aterrizaje al sitio principal
//index.jsx ReactDOM.render( (<BrowserRouter><App/></BrowserRouter>), document.getElementById('root') ); //App.jsx render() { return <div> <Switch> <Route exact path='/' component={Lander}/> <Route path='/vadatajs' component={Vadatajs}/> </Switch> </div> }
https://jsfiddle.net/Martins_Abilevs/4jko7arp/11/
ups, encontré que usas un enrutador diferente ... lo siento, entonces tal vez este violín sea útil para ti
https://fiddle.jshell.net/terda12/mana88Lm/
tal vez la clave de la solución esté oculta en línea para la función principal de renderizado.
Router.run(routes, function(Handler) { React.render(<Handler />, document.getElementById('container')); });
fuente
Estaba enfrentando un problema similar que resolví como este, por favor, eche un vistazo, espero que esté funcionando.
Debe utilizar la función componentWillReceiveProps en su componente.
hizo clic en un enlace por primera vez llamando a la URL www.example.com/content1/ se ejecuta componenteDidMount ().
Ahora, cuando haga clic en otro enlace, diga www.example.com/content2/ se llama al mismo componente, pero esta vez el prop cambia y puede acceder a este nuevo prop en componentWillReceiveProps (nextProps) que puede usar para llamar a API O dejar el estado en blanco y obtener nuevo datos.
componentWillReceiveProps(nextProps){ //call your API and update state with new props }
fuente
Para mi, tuve:
export MyClass extends React.Component
con:
export default withRouter(MyClass)
Mientras tanto, en mi App.js, tuve:
import { MyClass } from './MyClass'
Los que juegan en casa pueden ver mi problema. No estaba obteniendo la importación con el enrutador pasado a las clases secundarias. Para limpiar esto, moví la llamada withRouter a la declaración del componente Route:
<Router exact path={'/myclass'} component={withRouter(MyClass)} />
De vuelta en MyClass, lo cambié a una exportación predeterminada:
export default MyClass extends React.Component
Y luego, finalmente, en App.js, cambié mi importación a:
import MyClass from './MyClass'
Ojalá esto ayude a alguien. Esto asegura que no tuviera dos formas de exportar la misma clase, evitando así el prefijo withRouter .
fuente
Prueba esto,
import React from "react"; import ReactDOM from "react-dom"; import Users from "./components/Users"; import { Router, Route } from "react-router"; import Details from "./components/Details"; ReactDOM.render(( <Router> <Route path="/" component={Wrapper} > <IndexRoute component={Users} /> <Route path="/details" component={Details} /> </Route> </Router> ), document.getElementById('app'))
fuente
Debería comprobar esto: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md
Por lo tanto, definitivamente no es
Users
oDetails
, porque se procesan directamente por<Route>
, y selocation
pasará aprops
.Me pregunto, ¿por qué necesita el
<div>
entre<BrowserRouter>
y<Route>
? Elimínelo y avíseme si funciona.fuente
Tuve un problema similar con un diseño condicional:
class LayoutSwitcher extends Component { render () { const isLoggedIn = this.props.isLoggedIn return ( <React.Fragment> { isLoggedIn ? <MainLayout {...this.props} /> : <Login /> } </React.Fragment> ) } }
y reescribió las condiciones así:
render () { const isLoggedIn = this.props.isLoggedIn if (isLoggedIn) { return <MainLayout {...this.props} /> } return <Login /> }
Esto lo solucionó. En mi caso, parece que se perdió el contexto.
fuente
Tengo el mismo problema. No creo que en este caso necesite agregar el prop withRouter, solo verifique en su NavLink que escriba el nombre de la ruta correcta como detalles. para la ruta intente comenzar desde la ruta específica a la general como
<Route path="/details" component={Details} /> <Route path="/" component={Users} />
en su NavLink debería ser algo como esto
<NavLink className="nav-link" to="/details"> details<span className="sr-only">(current)</span> </NavLink>
un comentario para la importación, es mejor comenzar importando todo lo relacionado con React después de importar el otro módulo como este:
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter } from 'react-router-dom'; import Users from "./components/Users"; import { Router, Route } from "react-router"; import Details from "./components/Details";
ven así:
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter } from 'react-router-dom'; import { Router, Route } from "react-router"; import Users from "./components/Users"; import Details from "./components/Details";
fuente
En mi caso, cambiar a HashRouter en lugar de BrowserRouter resolvió mi problema
fuente
Tuve el mismo problema y lo solucioné al importar el historial de la carpeta @types en node_modules. Lo importé de npm (npm i @history)
fuente
Yo también encontré problemas.
https://github.com/chengjianhua/templated-operating-system
Y probé las soluciones mencionadas por Shubham Khatri, pero no funciona.
Resolví este problema, tal vez pueda ayudarte.
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md
De acuerdo con el documento de guía anterior, cuando usa
PureComponent
o usa con herramientas de administración de estado comoredux
,mobx
... Puede bloquear la actualización de su ruta. Verifique el componente de su ruta, asegúrese de no bloquear la reproducción de su componente.fuente
intente agregar prop forceRefresh = {true} a BrowserRouter (enrutador)
import {BrowserRouter as Router} from "react-router-dom"; <Router forceRefresh={true}> /// your <switch> and <route> </Router>
esto funciona para mi.
por cierto no es una solución real: D
fuente