w3schools property img attribute javascript reactjs redux

javascript - property - Navegar mediante programación usando react-router



title label html (8)

Estoy desarrollando una aplicación en la que compruebo si el usuario no ha loggedIn Tengo que mostrar el formulario de inicio de sesión; de lo contrario, dispatch una action que cambiaría la ruta y cargaría otro componente. Aquí está mi código:

render() { if (isLoggedIn) { // dispatch an action to change the route } // return login component <Login /> }

¿Cómo puedo lograr esto ya que no puedo cambiar los estados dentro de la función de renderizado?


Aquellos que enfrentan problemas para implementar esto en react-router v4 . Aquí hay una solución de trabajo para navegar a través de la aplicación Reaccionar mediante programación.

history.js

function PrivateRoute({ component: Component, ...rest }) { return ( <Route {...rest} render={props => (localStorage.token) ? <Component {...props} /> : ( <Redirect to={{ pathname: ''/signin'', state: { from: props.location }, }} /> ) } /> ); }

App.js O Route.jsx. Pase la historia como accesorio a su enrutador.

export default ( <main> <Switch> <Route exact path="/signin" component={SignIn} /> <Route exact path="/signup" component={SignUp} /> <PrivateRoute path="/" component={Home} /> </Switch> </main> );

Puede usar push() para navegar.

render(){ return ( <div> { this.props.redirect ? <Redirect to="/" /> :'''' } <div> add here component codes </div> </div> ); }

Todo gracias a este comentario: https://github.com/ReactTraining/react-router/issues/3498#issuecomment-301057248


En react-router versión 4:

import React from ''react'' import { BrowserRouter as Router, Route, Redirect} from ''react-router-dom'' const Example = () => ( if (isLoggedIn) { <OtherComponent /> } else { <Router> <Redirect push to="/login" /> <Route path="/login" component={Login}/> </Router> } ) const Login = () => ( <h1>Form Components</h1> ... ) export default Example;


Este es mi identificador loggedIn . react-router v4

PrivateRoute permite ingresar la path si el usuario ha iniciado sesión y guarda el token en localStorge

import createHistory from ''history/createBrowserHistory'' export default createHistory()

Defina todas las rutas en su aplicación aquí

import { Router, Route } from ''react-router-dom'' import history from ''./history'' ... <Router history={history}> <Route path="/test" component={Test}/> </Router>



Otra alternativa es manejar esto usando acciones asincrónicas de estilo Thunk (que son seguras / se les permite tener efectos secundarios).

Si usa Thunk, puede inyectar el mismo objeto de history tanto en su componente <Router> como en las acciones de Thunk usando thunk.withExtraArgument , de esta manera:

import React from ''react'' import { BrowserRouter as Router, Route, Redirect} from ''react-router-dom'' import { createBrowserHistory } from "history" import { applyMiddleware, createStore } from "redux" import thunk from "redux-thunk" const history = createBrowserHistory() const middlewares = applyMiddleware(thunk.withExtraArgument({history})) const store = createStore(appReducer, middlewares) render( <Provider store={store} <Router history={history}> <Route path="*" component={CatchAll} /> </Router </Provider>, appDiv)

Luego, en sus creadores de acción, tendrá una instancia de history segura para usar con ReactRouter, por lo que puede desencadenar un evento Redux normal si no está conectado:

// meanwhile... in action-creators.js export const notLoggedIn = () => { return (dispatch, getState, {history}) => { history.push(`/login`) } }

Otra ventaja de esto es que la url es más fácil de manejar, por lo que podemos poner información de redireccionamiento en la cadena de consulta, etc.

Puede intentar seguir haciendo esta verificación en sus métodos de Render, pero si causa problemas, puede considerar hacerlo en componentDidMount o en cualquier otra parte del ciclo de vida (¡aunque también entiendo el deseo de seguir con los competidores funcionales sin estado!)

Todavía puede usar Redux y mapDispatchToProps para inyectar el creador de la acción en su componente, por lo que su componente todavía está conectado libremente a Redux.


Pude usar el history dentro del componente funcional sin estado, usando withRouter de la siguiente manera (necesario ignorar la advertencia de mecanografía):

import { withRouter } from ''react-router-dom''; ... type Props = { myProp: boolean }; // @ts-ignore export const MyComponent: FC<Props> = withRouter(({ myProp, history }) => { ... })


Teniendo en cuenta que está utilizando react-router v4

Use su componente con withRouter y use history.push de los accesorios para cambiar la ruta. withRouter usar withRouter solo cuando su componente no recibe los accesorios del Router , esto puede suceder en los casos en que su componente sea un elemento anidado de un componente representado por el enrutador y no le haya pasado los accesorios del enrutador o cuando el componente no está vinculado al enrutador y se representa como un componente separado de las rutas.

import {withRouter} from ''react-router''; class App extends React.Component { ... componenDidMount() { // get isLoggedIn from localStorage or API call if (isLoggedIn) { // dispatch an action to change the route this.props.history.push(''/home''); } } render() { // return login component return <Login /> } } export default withRouter(App);

Nota IMPORTANTE

Si está utilizando withRouter para evitar que las actualizaciones sean bloqueadas por shouldComponentUpdate , es importante que withRouter envuelva el componente que implementa shouldComponentUpdate . Por ejemplo, cuando usa Redux:

// Esto se shouldComponentUpdate

withRouter(connect(...)(MyComponent))

// Esto no lo hace

connect(...)(withRouter(MyComponent))

o podrías usar Redirect

import {withRouter} from ''react-router''; class App extends React.Component { ... render() { if(isLoggedIn) { return <Redirect to="/home"/> } // return login component return <Login /> } }

Con react-router v2 or react-router v3 , puede utilizar el context para cambiar dinámicamente la ruta como

class App extends React.Component { ... render() { if (isLoggedIn) { // dispatch an action to change the route this.context.router.push(''/home''); } // return login component return <Login /> } } App.contextTypes = { router: React.PropTypes.object.isRequired } export default App;

o usar

import { browserHistory } from ''react-router''; browserHistory.push(''/some/path'');


import history from ''./history'' ... render() { if (isLoggedIn) { history.push(''/test'') // this should change the url and re-render Test component } // return login component <Login /> }