Reactjsの新しいreact-router-domでRedirectを使うには?

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

コードです:

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;
質問へのコメント (6)
ソリューション

setStateを使用して、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 ;
     }

     return ;
}

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


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

でも、こうしなければならない理由があるんでしょうね。

解説 (6)

ここでは、タイトルに対応した小さな例を挙げます。公式の例と同様に、言及された例はすべて複雑だと私は考えています。

es2015をトランスパイルする方法と、サーバーがリダイレクトを処理できるようにする方法を知っておく必要があります。以下は、express用のスニペットです。これに関するより多くの情報は、こちらにあります。

他のすべてのルートよりも下に置くようにしてください。

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

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

これは.jsxファイルです。一番長い経路が最初に来て、より一般的になっていることに注目してください。最も一般的な経路は、正確な属性を使用します。

// 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 = () => (





       ()} />          



);

ReactDOM.render(, root); 
解説 (3)

好きな機能内で呼び出すだけです。

this.props.history.push('/main');
解説 (2)

こんな感じで試してみてください。

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
?  
: 
)}

  render() {
    return (
      <div className={styles.section}>
        <div className={styles.container}>

         {renderMe()}
          <Footer />
        </div>
      </div>
    );
  }
}

export default SignUpPage;
解説 (3)

React Router v5では、[useHistory()フック][1]のおかげで、history.push()を使用して簡単にリダイレクトできるようになりました。


「react-router」から{useHistory}をインポートします。

関数HomeButton(){。
  history = useHistory()とします。

  関数handleClick(){。
    history.push( "/ home")。
  }。

  戻る(。
    < button type = "button" onClick = {handleClick}>。
      家に帰れ。
    < / button>。
  )。
}。
``。

  [1]:https://reacttraining.com/react-router/web/api/Hooks/usehistory。
解説 (0)

または、「withRouter」を使用することもできます。 「history」オブジェクトのプロパティと、最も近い「< Route>」の「match」に、「withRouter」高次コンポーネントを介してアクセスできます。 withRouterは、レンダリングするたびに、更新された matchlocation、および historyプロップをラップされたコンポーネントに渡します。

import React from "react"
import PropTypes from "prop-types"
import { withRouter } from "react-router"

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  }

  render() {
    const { match, location, history } = this.props

    return <div>You are now at {location.pathname}</div>
  }
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)

またはただ:

import { withRouter } from 'react-router-dom'

const Button = withRouter(({ history }) => (
   { history.push('/new-location') }}
  >
    Click Me!

))
解説 (0)

。 "react": "^ 16.3.2"、。 "react-dom": "^ 16.3.2"、。 "react-router-dom": "^ 4.2.2"。

別のページ(私の場合はページについて)に移動するには、「prop-types」をインストールしました。 次に、対応するコンポーネントにインポートします。また、「this.context.router.history.push( '/ about')」を使用しました。

私のコードは、です。

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
  };
解説 (0)

別のコンポーネントに移動するには、 this.props.history.push( '/ main');を使用できます。

import React, { Component, Fragment } from 'react'

class Example extends Component {

  redirect() {
    this.props.history.push('/main')
  }

  render() {
    return (

        {this.redirect()}

    );
   }
 }

 export default Example
解説 (1)

この目的でhocを書き込んで、メソッド呼び出しリダイレクトを書き込むことができます。これがコードです。

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 
    }
    return (



    );
};

export default RedirectHoc;
解説 (0)

または、React条件付きレンダリングを使用することもできます。

``。 「react-router」から{Redirect}をインポートします。 React、「react」から{Component}をインポートします。

クラスUserSignupはコンポーネント{を拡張します。 コンストラクター(小道具){。 super(props);。 this.state = {。 リダイレクト:false。 }。 }。 render(){。

< React.Fragment>。 {this.state.redirect&& < Redirect to = "/ signin" />} //サインインルートにリダイレクトされます。 }。 < / React.Fragment>。 }。 ``。
解説 (0)

別のコンポーネントに移動する最も簡単なソリューションは(例。 アイコンをクリックしてメールコンポーネントに移動します):

 { this.props.history.push('/mails') } }
/>
解説 (0)