1. ホーム
  2. javascript

[解決済み] Reactjsの新しいreact-router-domでRedirectを使用する方法

2022-03-01 10:58:53

質問

ReactでWebアプリケーションを開発する際に、デフォルトになっているreact-router-domという最終バージョンのreact-routerモジュールを使用しています。POSTリクエストの後にリダイレクトを行う方法を知りたいです。このコードを作っているのですが、リクエストの後、何も起こりません。私はウェブ上でレビューしますが、すべてのデータは反応ルータの以前のバージョンに関するものであり、最後の更新ではありません。

コード

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;

解決方法は?

を使用する必要があります。 setState をレンダリングするプロパティを設定します。 <Redirect> の中にある render() メソッドを使用します。

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/>;
}

また、公式ドキュメントに例が掲載されています。 https://reacttraining.com/react-router/web/example/auth-workflow


ということで、APIコールはサービスの中に入れるなどした方がいいと思います。そうすれば history オブジェクトを使用してプログラム的にルーティングします。このように reduxとの統合 が動作します。

でも、このようにするのには理由があるのでしょう。