在Formik中添加react-bootstrap警报以处理handleSubmit

时间:2019-05-21 02:26:57

标签: javascript reactjs react-bootstrap formik

我正在尝试向我的Formik表单添加一个react-bootstrap警报,以便handleSubmit包括向用户发送该表单已提交的警报。

我使用了Alert的react-bootstrap记录形式,但是我不得不更改最后一行,因为这似乎不起作用(错误表明如果我使用的react-bootstrap记录形式没有导出任何内容,警报。

我的警报是:

import React from 'react';

import {
    Alert,
    Button,

  } from "react-bootstrap";

class AlertDismissible extends React.Component {
    constructor(props) {
      super(props);

      this.state = { show: true };
    }

    render() {
      const handleHide = () => this.setState({ show: false });
      const handleShow = () => this.setState({ show: true });
      return (
        <>
          <Alert show={this.state.show} variant="light">
            <Alert.Heading>Thanks for your interest </Alert.Heading>
            <p>
              We'll be in touch with login details shortly.
            </p>
            <hr />
            <div className="d-flex justify-content-end">
              <Button onClick={handleHide} variant="outline-success">
                Close
              </Button>
            </div>
          </Alert>

          {!this.state.show && <Button onClick={handleShow}>Show Alert</Button>}
        </>
      );
    }
  }


export default AlertDismissible;

文档最后一行显示为:

render(<AlertDismissible />);

如果我尝试使用它,则会出现一条错误消息,提示未定义渲染,并且未导出任何内容。所以-我用最后一行替换了那一行。

然后,在我的表格中,我有:

handleSubmit = (formState, { resetForm }) => {
        // Now, you're getting form state here!
        const payload = {
            ...formState,
            role: formState.role.value,
            createdAt: firebase.firestore.FieldValue.serverTimestamp()
          }
          console.log("formvalues", payload);

        fsDB
          .collection("register")
          .add(payload)
          .then(docRef => {
            resetForm(initialValues);

          })
          .then => {<AlertDismissible />}

          .catch(error => {
            console.error("Error adding document: ", error);
          });
    }

我实际上并不知道如何使警报正常工作(上面的then陈述是一种猜测-我找不到任何示例。这种猜测给出了一个错误,提示:

Parsing error: Unexpected token, expected ";"

我尝试添加“;”在我可以想到的每个地方都放一个,但是它不断产生错误。

如果我这样尝试:

.then(<AlertDismissible />)

我没有收到任何错误,并且表单已提交,但未显示警报。

有人知道如何在handle提交功能中调用react-bootstrap警报吗?

“提交”按钮具有:

<Button
  variant="outline-primary"
  type="submit"
  style={style3}
  id="submitRegistration"
  onClick={handleSubmit}
  disabled={!dirty || isSubmitting}>
   Register
</Button>

onSubmit具有:

onSubmit={
  this.handleSubmit
}

我的整个表单如下:

import React from 'react';
import { Link } from "react-router-dom";
import { Formik, Form, Field, ErrorMessage, withFormik } from "formik";
import * as Yup from "yup";
import Select from "react-select";
import { fsDB, firebase, settings } from "../../firebase";
import Temporarynav from '../navigation/Temporarynav.jsx';
import Demo from '../landing/Demo.jsx';
import Footer from '../footer/Footer.jsx';
import "./preregister/Form.css";
import AlertDismissible from '../auth/preregister/Alert';


import {
    Badge,
    Button,
    Col,
    ComponentClass,
    Feedback,
    FormControl,
    FormGroup,
    Table,
    Row,
    Container
  } from "react-bootstrap";
import Alert from 'react-bootstrap/Alert';

  const style1 = {
    width: "60%",
    margin: "auto"
  };

  const style2 = {
    paddingTop: "2em"
  };

  const style3 = {
    marginRight: "2em"
  };



const initialValues = {
firstName: "",
lastName: "",
email: "",
role: "",
consent: false,
createdAt: ''
}


class PreregForm extends React.Component {

    // constructor(props) {
    //   super(props);

    //   // the flag isFormDone will control where you will show the Alert component
    //   this.state = {
    //     isFormDone: false
    //   };
    // }
    handleSubmit = (formState, { resetForm }) => {
        // Now, you're getting form state here!
        const payload = {
            ...formState,
            role: formState.role.value,
            createdAt: firebase.firestore.FieldValue.serverTimestamp()
          }
          console.log("formvalues", payload);

        fsDB
          .collection("preregistrations")
          .add(payload)
          .then(docRef => {
            resetForm(initialValues);

          })
          .then(() => {
            // Here is where you flag your form completion and allow the alert to be shown.
            // this.setState((prevState) => {...prevState, isFormDone: true});
          .catch(error => {
            console.error("Error adding document: ", error);
          });
    }

    render() {
        const options = [
            { value: "academic", label: "Academic Researcher" },
            { value: "student", label: "Student (inc PhD)" },
        ] 

        // const {isFormDone} = this.state;

        return(
            <Formik
                initialValues={initialValues}
                validationSchema={Yup.object().shape({
                    firstName: Yup.string().required("First Name is required"),
                    lastName: Yup.string().required("Last Name is required"),
                    email: Yup.string()
                        .email("Email is invalid")
                        .required("Email is required"),
                    role: Yup.string().nullable().required(
                        "It will help us get started if we know a little about your background"
                    ),
                    consent: Yup.boolean().oneOf(
                        [true],
                        "You must accept the Terms of Use and Privacy Policy"
                    )
                })}  
                onSubmit={
                  this.handleSubmit
                }
                render={({ 
                    errors, 
                    status, 
                    touched, 
                    setFieldValue,
                    setFieldTouched, 
                    handleSubmit, 
                    isSubmitting, 
                    dirty, 
                    values 
                }) => {

                  return (
                    <div>  
                    <Temporarynav />  
                    <Form style={style1}>
                      <h1 style={style2}>Get Started</h1>
                      <p>
                        We're almost ready to open this up to the research community. By
                        registering now, you'll be first in line when the doors open.
                      </p>
                      <div className="form-group">
                        <label htmlFor="firstName">First Name</label>
                        <Field
                          name="firstName"
                          type="text"
                          className={
                            "form-control" +
                            (errors.firstName && touched.firstName ? " is-invalid" : "")
                          }
                        />
                        <ErrorMessage
                          name="firstName"
                          component="div"
                          className="invalid-feedback"
                        />
                      </div>
                      <div className="form-group">
                        <label htmlFor="lastName">Last Name</label>
                        <Field
                          name="lastName"
                          type="text"
                          className={
                            "form-control" +
                            (errors.lastName && touched.lastName ? " is-invalid" : "")
                          }
                        />
                        <ErrorMessage
                          name="lastName"
                          component="div"
                          className="invalid-feedback"
                        />
                      </div>
                      <div className="form-group">
                        <label htmlFor="email">Email</label>
                        <Field
                          name="email"
                          type="text"
                          placeholder="Please use your work email address"
                          className={
                            "form-control" +
                            (errors.email && touched.email ? " is-invalid" : "")
                          }
                        />
                        <ErrorMessage
                          name="email"
                          component="div"
                          className="invalid-feedback"
                        />
                      </div>
                      <div className="form-group">
                        <label htmlFor="role">
                        Which role best describes yours?
                        </label>

                        <Select
                        key={`my_unique_select_keyrole`}
                        name="role"
                        className={
                            "react-select-container" +
                            (errors.role && touched.role ? " is-invalid" : "")
                        }
                        classNamePrefix="react-select"
                        value={values.role}
                        onChange={selectedOptions => {
                            // Setting field value - name of the field and values chosen.
                            setFieldValue("role", selectedOptions)}
                            }
                        onBlur={setFieldTouched}
                        options={options}
                        />
                        {errors.role && touched.role && 
                        <ErrorMessage
                        name="role"
                        component="div"
                        className="invalid-feedback d-block"
                        />}
                      </div>


                      <div className="form-group">
                        <div className="checkbox-wrapper">
                            <Field
                              name="consent"
                              type="checkbox"
                              checked={values.consent}
                              className={
                                "checkbox" +
                                (errors.consent && touched.consent ? " is-invalid" : "")
                              }
                            />
                        <label htmlFor="consent" className="checkbox_label_wrapper">
                          You must accept the{" "}
                          <Link className="links" to={"/Terms"}>
                            Terms of Use
                          </Link>{" "}
                          and{" "}
                          <Link className="links" to={"/Privacy"}>
                            Privacy Policy
                          </Link>


                        </label>
                        </div>

                        {errors.consent && touched.consent && 
                        <ErrorMessage
                          name="consent"
                          component="div"
                          className="invalid-feedback d-block"
                        />
                        }
                      </div>


                      <div className="form-group">
                        <Button
                          variant="outline-primary"
                          type="submit"
                          style={style3}
                          id="submitRegistration"
                          onClick={handleSubmit}
                          disabled={!dirty || isSubmitting}

                          >
                          Register
                        </Button>
                      </div>
                    </Form>
                    <Demo />
                    <Footer />
                    </div>


                  );
                }
                } 
            /> 
        )    

    }
}            

export default PreregForm;

下一次尝试

当我尝试使用Julius解决方案时,会显示警报,但是会显示在表单下方的页脚中,而不是弹出警报。

2 个答案:

答案 0 :(得分:3)

使用状态和条件渲染。在渲染中,不使用将组件集的状态返回到变量中,而是使用条件渲染来检查该值是否为真。

getStructure

在渲染中

handleSubmit = (formState, { resetForm }) => {
  // Now, you're getting form state here!
  const payload = {
    ...formState,
    role: formState.role.value,
    createdAt: firebase.firestore.FieldValue.serverTimestamp()
  };
  console.log('formvalues', payload);

  fsDB
    .collection('register')
    .add(payload)
    .then(docRef => {
      resetForm(initialValues);
    })
    .then(e => this.setState({ alert: true }))

    .catch(error => {
      console.error('Error adding document: ', error);
    });
};

Example Demo

填写表格

render() {
 ...
  return(
 ....
   {this.state.alert && <AlertDismissible />}
 ...
  )
}

答案 1 :(得分:0)

您无法在then函数中返回类似组件。 您应该管理一个状态标志,该标志根据表单完成情况显示警报。

也许您可以在此处显示的submit处共享您的整个组件,以便我们为您提供更多帮助(如果您更新问题,将会更新答案)。

但是我认为这将遵循以下几条原则:

class MyFormComponent extends React.Component {

  constructor(props) {
    super(props);

    // the flag isFormDone will control where you will show the Alert component
    this.state = {
      isFormDone: false
    };
  }

  /** Here your form handling as you posted */
  handleSubmit = (formState, { resetForm }) => {
      const payload = {
          ...formState,
          role: formState.role.value,
          createdAt: firebase.firestore.FieldValue.serverTimestamp()
        }
        console.log("formvalues", payload);

      fsDB
        .collection("register")
        .add(payload)
        .then(docRef => {
          resetForm(initialValues);

        })
        .then(() => {
          // Here is where you flag your form completion and allow the alert to be shown.
          this.setState((prevState) => ({...prevState, isFormDone: true}));
        })
        .catch(error => {
          console.error("Error adding document: ", error);
        });
  }


  render() {

    const {isFormDone} = this.state;

    // this will only render the Alert when you complete your form submission
    const alert = isFormDone ? <AlertDismissible/> : null;

    return(
      {/* syntax sugar for React Fragment */}
      <> 
        {/* if it is null, it won't render anything */}
        {alert}

        {/* Your Form here with your handler */}
        {/* ... */}
      </>
      );

  }

}