J'utilise la dernière version du module react-router, appelée react-router-dom, qui est devenue la valeur par défaut lors du développement d'applications Web avec React. Je veux savoir comment effectuer une redirection après une demande POST. Je fais ce code, mais après la demande, rien ne se passe. Je passe en revue sur le Web, mais toutes les données concernent les versions précédentes du routeur de réaction, et non avec la dernière mise à jour.
Code:
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;
Vous devez utiliser setState
pour définir une propriété qui rendra le <Redirect>
dans votre méthode render()
.
Par exemple.
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/>;
}
Vous pouvez également voir un exemple dans la documentation officielle: https://reacttraining.com/react-router/web/example/auth-workflow
Cela dit, je vous suggérerais de placer l'appel API dans un service ou quelque chose du genre. Ensuite, vous pouvez simplement utiliser l'objet history
pour router par programme. Voici comment fonctionne integration avec redux .
Mais je suppose que vous avez vos raisons pour le faire de cette façon.
Ici, un petit exemple en réponse au titre car tous les exemples mentionnés sont compliqués à mon avis ainsi que celui officiel.
Vous devez savoir transpiler es2015 et permettre à votre serveur de gérer la redirection. Voici un extrait pour express. Plus d’informations sur ce sujet peuvent être trouvées ici .
Assurez-vous de mettre ceci en dessous de tous les autres itinéraires.
const app = express();
app.use(express.static('distApp'));
/**
* Enable routing with React.
*/
app.get('*', (req, res) => {
res.sendFile(path.resolve('distApp', 'index.html'));
});
C'est le fichier .jsx. Remarquez comment le chemin le plus long vient en premier et obtenez plus général. Pour les itinéraires les plus généraux, utilisez l'attribut exact.
// Absolute imports
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
// Relative 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);
Essayez quelque chose comme ça.
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: {},
callbackResponse: null,
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
});
}
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({
callbackResponse: {response.data},
});
}).catch((error) => {
const errors = error.response.data.errors ? error.response.data.errors : {};
errors.summary = error.response.data.message;
this.setState({
errors
});
});
}
const renderMe = ()=>{
return(
this.state.callbackResponse
? <SignUpForm
onSubmit={this.processForm}
onChange={this.changeClient}
errors={this.state.errors}
client={this.state.client}
/>
: <Redirect to="/"/>
)}
render() {
return (
<div className={styles.section}>
<div className={styles.container}>
<img src={require('./images/Lisa_principal_bg.png')} className={styles.fullImageBackground} />
{renderMe()}
<Footer />
</div>
</div>
);
}
}
export default SignUpPage;
Pour naviguer vers un autre composant, vous pouvez utiliser this.props.history.Push('/main');
import React, { Component, Fragment } from 'react'
class Example extends Component {
redirect() {
this.props.history.Push('/main')
}
render() {
return (
<Fragment>
{this.redirect()}
</Fragment>
);
}
}
export default Example
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-router-dom": "^4.2.2"
Pour naviguer vers une autre page (page A propos de mon cas), j'ai installé prop-types
. Puis je l’importe dans le composant correspondant.Et j’ai utilisé this.context.router.history.Push('/about')
.
Mon code est,
import React, { Component } from 'react';
import '../assets/mystyle.css';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
export default class Header extends Component {
viewAbout() {
this.context.router.history.Push('/about')
}
render() {
return (
<header className="App-header">
<div className="myapp_menu">
<input type="button" value="Home" />
<input type="button" value="Services" />
<input type="button" value="Contact" />
<input type="button" value="About" onClick={() => { this.viewAbout() }} />
</div>
</header>
)
}
}
Header.contextTypes = {
router: PropTypes.object
};
La solution la plus simple pour naviguer vers un autre composant est la suivante (Exemple: naviguez vers le composant mails en cliquant sur l'icône):
<MailIcon
onClick={ () => { this.props.history.Push('/mails') } }
/>
Appelez-le simplement dans la fonction de votre choix.
this.props.history.Push('/main');
vous pouvez écrire un hoc à cette fin et écrire une redirection d'appel de méthode, en voici le code
import React, {useState} from 'react';
import {Redirect} from "react-router-dom";
const RedirectHoc = (WrappedComponent) => () => {
const [routName, setRoutName] = useState("");
const redirect = (to) => {
setRoutName(to);
};
if (routName) {
return <Redirect to={"/" + routName}/>
}
return (
<>
<WrappedComponent redirect={redirect}/>
</>
);
};
export default RedirectHoc;