Comment utiliser la redirection dans le nouveau react-router-dom de Reactjs

J'utilise la dernière version du module react-router, nommé react-router-dom, qui est devenu la valeur par défaut pour développer des applications web. Je veux savoir comment faire une redirection après une requête POST. J'ai fait 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 react, 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;
53
demandé sur maoooricio 2017-04-05 14:42:11

6 réponses

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 aussi voir un exemple dans la documentation officielle: https://reacttraining.com/react-router/web/example/auth-workflow


Cela dit, je vous suggère de mettre L'appel API dans un service ou quelque chose. Ensuite, vous pouvez simplement utiliser l'objet history pour router par programme. C'est ainsi que l'intégration avec redux travail.

Mais je suppose que vous avez vos raisons de le faire de cette façon.

92
répondu Sebastian Sebald 2017-09-02 20:46:51

Voici 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 comment transpiler es2015 ainsi que rendre votre serveur capable de gérer la redirection. Voici un extrait pour express. Plus d'informations à ce sujet peuvent être trouvées ici .

Assurez-vous de mettre ceci en dessous de toutes les autres routes.

const app = express();
app.use(express.static('distApp'));

/**
 * Enable routing with React.
 */
app.get('*', (req, res) => {
  res.sendFile(path.resolve('distApp', 'index.html'));
});

Ceci est le .jsx fichier. Remarquez comment le chemin le plus long vient en premier et devient plus général. Pour les routes les plus générales utilisent 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); 
10
répondu Matthis Kohli 2017-07-21 13:58:00

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;
3
répondu KornholioBeavis 2017-04-05 12:41:33

"react": "^16.3.2", "react-dom": "^16.3.2", "react-router-dom": "^4.2.2"

Pour naviguer vers une autre page (à propos de la page dans mon cas), j'ai installé prop-types. Ensuite, je l'importe dans le composant correspondant.Et j'ai utilisé this.context.router.history.push('/about').Et il arrive à naviguer.

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
  };
1
répondu sojan 2018-04-25 13:02:29

Pour accéder à 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
0
répondu Morris S 2018-07-24 13:44:04

J'ai essayé simple hack. Ne peut pas bonne, mais cela fonctionne pour moi. J'ai écrit ce code simple à l'intérieur des événements. Cela redirigera vers l'emplacement spécifique du navigateur(/path)

handleSubmit () {
 axios.post(/**/)
  .then(() => {
    this.setState({ redirect: true }));
    window.location.href='/path';
  }
} 
-5
répondu KannanHudson 2018-01-05 14:50:18