【问题标题】:React.js - on form submit, post data to backend and redirect pageReact.js - 提交表单,将数据发布到后端并重定向页面
【发布时间】:2020-09-16 16:30:42
【问题描述】:

我正在做我的第一个 React 项目。

提交表单时我想做两件事:

  1. 将表单数据发布到后端
  2. 重定向到感谢页面

我可以使用 handleSubmit(下面的代码)将表单数据发布到后端,但正在寻找一种方法来合并重定向。

    handleSubmit = (event) => {
        event.preventDefault();
        try {
            await fetch('http://localhost:5000/results', {
                method: 'POST',
                headers:{
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(this.state)
                }).then(function(response){
                    console.log(response)
                    return response.json();
                });
            }
        catch (error){
            console.log(error);
        }
    }

这就是在表单上调用 handleSubmit 的方式

<form onSubmit={this.handleSubmit} 
             action="http://localhost:5000/results" method="post"
             >

这就是我想作为 handleSubmit 的一部分合并的内容

<Redirect  to="/thank-you/" />

编辑:withRouter/this.props.history.push

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


class Form extends React.Component {


handleSubmit = async event => {
        event.preventDefault();
        try {
            await fetch('http://localhost:5000/results', {
                method: 'POST',
                headers:{
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(this.state)
                }).then(function(response){
                    console.log(response)
                    return response.json();
                    this.props.history.push("/thankyou");
                });
            }
        catch (error){
            console.log(error);
        }
    }
}


export default withRouter(Form);

编辑2:重写handleSubmit,将BrowserRouter添加到App


//form.component.jsx

class Form extends React.Component {
  
   handleSubmit = (event) => {
        event.preventDefault();
        
        fetch('http://localhost:5000/results', {
                method: 'POST',
                headers:{
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(this.state)
                }).then((response) => response.json())
                  .then((json) => {
                      console.log(json)
                     this.props.history.push("/thank-you");
                })
            
        .catch((error) =>  console.log(error.message));
    };

export default Form;



//app.js

import { BrowserRouter, Route } from 'react-router-dom';

class App extends React.Component {
 return (
  
        <BrowserRouter>

          <Route exact path='/form' component= {Form}/>
          <Route exact path='/thank-you' component={ThankYou}/>

        </BrowserRouter>
);
}
export default App;

【问题讨论】:

  • 在您的.then() 中,设置一个状态变量,例如this.setState( { redirect: true } )(使用箭头函数进行回调,这样您就不会丢失正确的this)。现在您可以简单地将{ this.state.redirect &amp;&amp; &lt;Redirect to="/thank-you/" /&gt;} 添加到您的组件中。 (另请注意,您可以使用event.target.getAttribute('action') 从表单中获取url,或者从&lt;form&gt; 中删除action 属性)

标签: javascript reactjs


【解决方案1】:

您不能使用Redirect 组件以编程方式重定向用户。 Redirect 组件应该在 JSX 中渲染,以使其生效并重定向应用程序。

如果您使用的是功能组件,则可以在提交表单后使用react-router-dom 中的useHistory 挂钩来重定向用户。

import { useHistory } from 'react-router-dom';

function MyComponent() {
   ...
   const routerHistory = useHistory();  

   const handleSubmit = async event => {
        event.preventDefault();
        try {
            ...
            routerHistory.push('/new-route');
        }
        catch (error){
            console.log(error);
        }
    }

   ...
}

如果是类组件,您可以使用从反应路由器传递给直接子组件的history 属性。

class MyComponent extends React.Component {
   ...

   handleSubmit = async event => {
        event.preventDefault();
        try {
            ...
            this.props.history.push('/new-route');
        }
        catch (error){
            console.log(error);
        }
    }

   ...
}

如果你的类组件中没有定义history props,那么你可以使用withRouter高阶组件来确保路由props传递给你的组件。

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

class MyComponent extends React.Component {
   ...
}

export default withRouter(MyComponent);

旁注:在handleSubmit() 方法中,您将async-await 语法与promise-chaining 混合在一起。使用其中之一,但不能同时使用两者。我建议你使用async-await 语法。

仅使用async-await 语法,handleSubmit() 方法可以写成如下所示:

handleSubmit = async event => {
    event.preventDefault();

    try {
      const requestData = {
        method: 'POST',
        headers:{
           'Content-Type': 'application/json'
        },
        body: JSON.stringify(this.state)
      };

      const response = await fetch('http://localhost:5000/results', requestData);
      const data = await response.json();

      // do something with the data returned from the server as 
      // a result of POSt request
      ...
      
      // redirect
      this.props.history.push('/thank-you');
    
     } catch (error) {
        console.log(error);
     }
}

【讨论】:

  • 嗨-我尝试在return response.json();之前和return response.json()之后添加this.props.history.push('/thank-you');;两者似乎都没有被重定向到感谢页面。我错过了什么吗? (我也试过 withRouter)
  • 检查浏览器url是否改变。如果它没有改变,那么请编辑您的问题以显示代码在您进行答案中提到的更改时的样子
  • 浏览器 url 没有改变,它停留在表单页面上。后端部分仍然有效。我继续使用 withRouter 和 this.props.history.push 编辑帖子
  • return 语句之后的任何代码都是无法访问的代码。查看您的代码,您似乎根本不需要使用response。如果这样做,请确保将其保存在状态中,然后重定向应用程序。另外,正如我在回答末尾提到的,不要将 promise-chaining 与 async-await 语法混合使用,使用其中之一,而不是两者。
  • 看看this demo 是否能帮助您了解如何在 POST 请求后重定向。
【解决方案2】:

您必须在函数渲染中返回 &lt;Redirect to="/thank-you/" /&gt; 才能重定向。所以,我建议你应该设置一个带有组件&lt;Redirect to="/thank-you/" /&gt;的模态并在函数render中渲染它。

例子:

 state={
        modal: null,
    }

handleSubmit = async event => {
    event.preventDefault();
    try {
        await fetch('http://localhost:5000/results', {
            method: 'POST',
            headers:{
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(this.state)
        }).then(function(response){
            console.log(response)
            this.setState({modal: <Redirect  to="/thank-you/" />})
            return response.json();
        });
    }
    catch (error){
        console.log(error);
    }
}

render() {
    return <div>
        ...
        {this.state.modal}
    </div>
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    相关资源
    最近更新 更多