javascript - Cómo usar Redirect en la versión 5 de react-router-dom de Reactjs
Estoy utilizando la última versión del módulo react-router, llamado react-router-dom, que se ha convertido en el predeterminado al desarrollar aplicaciones web con React. Quiero saber cómo hacer una redirección después de una solicitud POST. He estado haciendo este código, pero después de la solicitud, no pasa nada. Revisé en la web, pero toda la información es sobre versiones anteriores de react router, y no sobre la última actualización.
Código :
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Redirect } from 'react-router'
import SignUpForm from '../../register/components/SignUpForm';
import styles from './PagesStyles.css';
import axios from 'axios';
import Footer from '../../shared/components/Footer';
class SignUpPage extends React.Component {
constructor(props) {
super(props);
this.state = {
errors: {},
client: {
userclient: '',
clientname: '',
clientbusinessname: '',
password: '',
confirmPassword: ''
}
};
this.processForm = this.processForm.bind(this);
this.changeClient = this.changeClient.bind(this);
}
changeClient(event) {
const field = event.target.name;
const client = this.state.client;
client[field] = event.target.value;
this.setState({
client
});
}
async processForm(event) {
event.preventDefault();
const userclient = this.state.client.userclient;
const clientname = this.state.client.clientname;
const clientbusinessname = this.state.client.clientbusinessname;
const password = this.state.client.password;
const confirmPassword = this.state.client.confirmPassword;
const formData = { userclient, clientname, clientbusinessname, password, confirmPassword };
axios.post('/signup', formData, { headers: {'Accept': 'application/json'} })
.then((response) => {
this.setState({
errors: {}
});
<Redirect to="/"/> // Here, nothings happens
}).catch((error) => {
const errors = error.response.data.errors ? error.response.data.errors : {};
errors.summary = error.response.data.message;
this.setState({
errors
});
});
}
render() {
return (
<div className={styles.section}>
<div className={styles.container}>
<img src={require('./images/lisa_principal_bg.png')} className={styles.fullImageBackground} />
<SignUpForm
onSubmit={this.processForm}
onChange={this.changeClient}
errors={this.state.errors}
client={this.state.client}
/>
<Footer />
</div>
</div>
);
}
}
export default SignUpPage;
Respuesta #1
Tienes que usar setState para establecer una propiedad que renderizará el <Redirect> dentro de tu método render().
Por ejemplo
class MyComponent extends React.Component {
state = {
redirect: false
}
handleSubmit () {
axios.post(/**/)
.then(() => this.setState({ redirect: true }));
}
render () {
const { redirect } = this.state;
if (redirect) {
return <Redirect to='/somewhere'/>;
}
return <RenderYourForm/>;
}
También puedes ver un ejemplo en la documentación oficial: https://reacttraining.com/react-router/web/example/auth-workflow
Dicho esto, te sugeriría que pongas la llamada a la API dentro de un servicio o algo similar. Luego podrías simplemente usar el objeto history para enrutar programáticamente. Así es como funciona la integración con redux.
Pero supongo que tienes tus razones para hacerlo de esta manera.
Respuesta #2
Aquí un pequeño ejemplo como respuesta al título ya que todos los ejemplos mencionados son complicados en mi opinión, al igual que el oficial.
Deberías saber cómo transpilar es2015, así como hacer que tu servidor pueda manejar la redirección. Aquí hay un fragmento para express. Más información relacionada con esto se puede encontrar aquí.
Asegúrate de poner esto debajo de todas las demás rutas.
const app = express();
app.use(express.static('distApp'));
/**
* Enable routing with React.
*/
app.get('*', (req, res) => {
res.sendFile(path.resolve('distApp', 'index.html'));
});
Este es el archivo .jsx. Observa cómo la ruta más larga aparece primero y se vuelve más general. Para las rutas más generales, usa el atributo exact.
// Relative imports
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
// Absolute imports
import YourReactComp from './YourReactComp.jsx';
const root = document.getElementById('root');
const MainPage= () => (
<div>Main Page</div>
);
const EditPage= () => (
<div>Edit Page</div>
);
const NoMatch = () => (
<p>No Match</p>
);
const RoutedApp = () => (
<BrowserRouter >
<Switch>
<Route path="/items/:id" component={EditPage} />
<Route exact path="/items" component={MainPage} />
<Route path="/yourReactComp" component={YourReactComp} />
<Route exact path="/" render={() => (<Redirect to="/items" />)} />
<Route path="*" component={NoMatch} />
</Switch>
</BrowserRouter>
);
ReactDOM.render(<RoutedApp />, root);
Respuesta #3
React Router v5 ahora te permite redirigir simplemente usando history.push() gracias al hook useHistory():
import { useHistory } from "react-router-dom"
function HomeButton() {
let history = useHistory()
function handleClick() {
history.push("/home")
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
)
}
Respuesta #4
Simplemente llámalo dentro de cualquier función que te guste.
this.props.history.push('/main');
