【问题标题】:React: How to route correctly on form submission?React:如何在表单提交时正确路由?
【发布时间】:2019-06-23 04:26:08
【问题描述】:

我有一个包含以下内容的单表单应用程序:

  1. 导航栏组件
  2. 表单组件(包含表单域)
  3. 复选框组件(条款和条件)
  4. 提交按钮组件
  5. ThankYouPage 组件

当用户填写表单时,组件 1-4 最初显示在屏幕上。当用户单击提交按钮时,我希望他或她被路由到感谢页面。在观看教程并添加路线后,当用户单击提交时,唯一发生的事情是,ThankYouPage 组件文本出现在表单下方。我希望所有其他组件都消失,唯一剩下的就是ThankYouPage 组件。谁能告诉我我做错了什么?

App.js

import React from 'react';
import NavBar from './Components/NavBar'
import Form from './Components/InfoForm'
import SubmitButton from './Components/SubmitButton';
import Container from '@material-ui/core/Container';
import Checkbox from './Components/Checkbox';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import ThankYou from './Components/ThankYou';

function App() {

    const [state, setState] = React.useState({
        checkbox: false,
    });

    const [values, setValues] = React.useState({
        name: '',
        age: '',
        email: ''
    });

    const handleChangeForm = name => event => {
      setValues({ ...values, [name]: event.target.value });
    };

    const handleChange = event => {
      setState({ ...state, [event.target.name]: event.target.checked });
    };

    return (
        <Router>
            <div>
                 <Container maxWidth="md">
                 <NavBar />
                 <Form values={values} handleChangeForm={handleChangeForm} />
                 <Checkbox name="checkbox" onChange={handleChange} checked={state.checkbox} />
                 <SubmitButton isEnabled={state.checkbox} values={values}/> 
                 </Container>     
            </div>
                <Route path="/thankyou" component={ThankYou} />
        </Router>
    );
}

export default App;

SubmitButton.js

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom';


export default function ContainedButtons(props) {
  const classes = useStyles();  

  const onClickBtn = () => {

    const textBuilder = () => {
      var doc = "";
      for (const key in props.values) {
       doc += key + ": " + props.values[key] + "<br/>";      
      }
      return doc;
    } 

    window.Email.send({
      Host : "smtp.elasticemail.com",
      Username : "mine@gmail.com",
      Password : "xxxx-xxxx-xxx-xxx",
      To : 'mine@gmail.com',
      From : "mine@gmail.com",
      Subject : "New Client Info",
      Body : textBuilder()
  }).then(
    message => alert(message)
  );
  };

    return (
      <div>
        <Link to="/thankyou">
          <Button variant="contained" color="primary" className={classes.button} disabled = {!props.isEnabled} type="submit" onClick={onClickBtn}>
            Submit
          </Button>
        </Link>
      </div>
    );
}

ThankYouPage.js

import React from 'react';

function ThankYou() {
  return (
    <div>
      <h2>Thank you and get ready to become a work of art!</h2>
    </div>
  );
}

export default ThankYou;

【问题讨论】:

  • 哦,我忘了提到使用 Link 标签也不是很好,因为它使我的按钮看起来很有趣(就像带有下划线的超链接)并且它在某种程度上影响了发送的能力SubmitButton 代码中的电子邮件。我使用它的唯一原因是因为教程说。

标签: javascript reactjs react-router


【解决方案1】:

您可以将Route 视为在路由匹配时将所述组件呈现在其位置的组件。

所以,当你有:

<Router>
  <div>
     <Container maxWidth="md">
        <NavBar />
        <Form values={values} handleChangeForm={handleChangeForm} />
        <Checkbox name="checkbox" onChange={handleChange} checked={state.checkbox} />
        <SubmitButton isEnabled={state.checkbox} values={values}/> 
     </Container>     
  </div>
  <Route path="/thankyou" component={ThankYou} />
</Router>

这意味着Container 内部的顶部是固定的,无论你去哪条路线。

相反,您需要在路由内渲染Container,以便在路由更改时它会消失。类似的东西:

<Router>
  <Route exact path="/" component={FormContainer} />
  <Route path="/thankyou" component={ThankYou} />
</Router>

提交表单时,可能需要执行验证。所以最好的方法是以编程方式导航。

submitForm = () => {
  // assuming this component is in a route
  const { router } = this.props'
  router.push("/thankyou");
}
render() {
  return (
    <form onSubmit={this.submitForm}>
     <button type="submit">Submit</button>
    </form>
  );
}

More info on Programmatic Navigation

关于您从客户端发送电子邮件,不要。访问您网站的每个人都可以访问该密码。编写服务器端脚本或使用mailto link

【讨论】:

  • 我不确定我是否理解如何执行您的建议。首先,我不确定如何使用我当前的代码/设置构建FormContainer。另外,我的SubmitButton 是一个独立于我的InfoForm 组件的组件。那么如何从提交按钮组件中引用表单呢?
  • 只是为了澄清我在上述评论的第一个问题中的意思,我如何在语法上获取所有组件(NavBar、Form、Checkbox、SubmitButton)并将它们放入FormContainer 组件中?
  • 您的第二条评论,是的。这就是要走的路
  • 我的问题是你是怎么做到的?您如何将它们全部放入FormContainer 组件中?我对 React 很陌生。
  • 似乎你制作了所有其他组件。只需创建一个新组件并在渲染中渲染所有这些
猜你喜欢
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多