javascript - 如何在reactjs中进行内部重定向?

标签 javascript reactjs material-ui formik

我对 React 有点陌生,想知道如何在 ReactJS 中内部重定向你的页面。我有两个页面,分别称为register 和register2。在注册页面中,我只是检查电子邮件是否存在于数据库中,如果不存在,则会重定向到 register2 页面,以使用用户名和密码创建完整帐户。然而,在地址栏中,显示像register2这样的东西看起来有点难看。所以我想知道是否有任何方法可以在内部重定向而不将地址栏中的地址更改为register2,以便它在整个帐户创建过程中保持注册状态。

我创建了一个codesandbox显示问题

注册.js

import React, { useState } from "react";
import { Formik } from "formik";
import TextField from "@material-ui/core/TextField";

import * as Yup from "yup";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import Link from "@material-ui/core/Link";
import Grid from "@material-ui/core/Grid";
import Box from "@material-ui/core/Box";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";

function Copyright() {
  return (
    <Typography variant="body2" color="textSecondary" align="center">
      <Link color="inherit" href="sad">
        New1
      </Link>{" "}
      {new Date().getFullYear()}
      {"."}
    </Typography>
  );
}

const useStyles = makeStyles(theme => ({
  paper: {
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main
  },
  form: {
    width: "100%",
    marginTop: theme.spacing(1)
  },
  submit: {
    margin: theme.spacing(3, 0, 2)
  }
}));

const Reg = props => {
  const classes = useStyles();
  const [loginError, setLoginError] = useState("");
  const [changed, setChanged] = useState(false);
  const [newpage, setNew] = useState(false);
  const handleSubmit = async (values, { setSubmitting }) => {
    const { email } = values;

    var body = {
      email: email
    };
    console.log(body);
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };
    const url = "/api/emailcheck";
    try {
      const response = await fetch(url, options);
      const text = await response.text();
      setSubmitting(false);
      setChanged(false);
      setNew(true);
      console.log(text);
      if (newpage) {
        props.history.push({
          pathname: "/register2",
          state: { email }
        });
        // props.history.push(`/register2/${email}`);
      } else if (text === "exists") {
        props.history.push(`/`);
      } else {
        setLoginError("Email is invalid");
      }
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <Formik
      initialValues={{ email: "" }}
      onSubmit={handleSubmit}
      //********Using Yup for validation********/

      validationSchema={Yup.object().shape({
        email: Yup.string()
          .email()
          .required("Required")
      })}
    >
      {props => {
        const {
          values,
          touched,
          errors,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit
        } = props;
        return (
          <>
            <Container component="main" maxWidth="xs">
              <CssBaseline />
              <div className={classes.paper}>
                <Avatar className={classes.avatar}>
                  <LockOutlinedIcon />
                </Avatar>
                <Typography component="h1" variant="h5">
                  Sign in
                </Typography>
                <form
                  className={classes.form}
                  onSubmit={handleSubmit}
                  noValidate
                >
                  <TextField
                    variant="outlined"
                    margin="normal"
                    required
                    fullWidth
                    id="email"
                    value={values.email}
                    label="Email Address"
                    name="email"
                    autoComplete="email"
                    onChange={e => {
                      setChanged(true);
                      handleChange(e);
                    }}
                    onBlur={handleBlur}
                    className={errors.email && touched.email && "error"}
                  />
                  {errors.email && touched.email && (
                    <div className="input-feedback" style={{ color: "red" }}>
                      {errors.email}
                    </div>
                  )}
                  {!changed && loginError && (
                    <div style={{ color: "red" }}>
                      <span>{loginError}</span>
                    </div>
                  )}

                  <Button
                    type="submit"
                    fullWidth
                    variant="contained"
                    color="primary"
                    className={classes.submit}
                    disabled={isSubmitting}
                  >
                    Next
                  </Button>
                  <Grid container justify="flex-end">
                    <Grid item>
                      <Link href="/" variant="body2">
                        Already have an account? Sign in
                      </Link>
                    </Grid>
                  </Grid>
                </form>
              </div>
              <Box mt={5}>
                <Copyright />
              </Box>
            </Container>
          </>
        );
      }}
    </Formik>
  );
};

export default Reg;

注册2.js

import React, { useState } from "react";
import { Formik } from "formik";
import TextField from "@material-ui/core/TextField";
import { withRouter, useHistory } from "react-router-dom";
import * as Yup from "yup";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import Link from "@material-ui/core/Link";
import Box from "@material-ui/core/Box";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";

function Copyright() {
  return (
    <Typography va riant="body2" color="textSecondary" align="center">
      <Link color="inherit" href="sad">
        New
      </Link>{" "}
      {new Date().getFullYear()}
      {"."}
    </Typography>
  );
}

const useStyles = makeStyles(theme => ({
  paper: {
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main
  },
  form: {
    width: "100%",
    marginTop: theme.spacing(1)
  },
  submit: {
    margin: theme.spacing(3, 0, 2)
  }
}));

const Reg2 = props => {
  const classes = useStyles();
  const [loginError, setLoginError] = useState("");
  const history = useHistory();
  const [changed, setChanged] = useState(false);
  const handleSubmit = async (values, { setSubmitting }) => {
    const { username, password } = values;
    var body = {
      username: username,
      password: password,
      email: history.location.state.email
    };
    console.log(body);
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };
    const url = "/api/register";
    try {
      const response = await fetch(url, options);
      const text = await response.text();
      setSubmitting(false);
      setChanged(false);
      console.log(text);
      if (text === "verifyemail") {
        props.history.push({
          pathname: "/verifyOtp",
          state: { email: body.email }
        });
        // props.history.push(`/verifyOtp/${username}`);
      } else {
        setLoginError("Username or Password is incorrect");
      }
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <Formik
      initialValues={{ username: "", password: "", confirmPassword: "" }}
      onSubmit={handleSubmit}
      //********Using Yup for validation********/

      validationSchema={Yup.object().shape({
        username: Yup.string().required("Required"),
        password: Yup.string()
          .required("No password provided.")
          .min(8, "Password is too short - should be 8 chars minimum.")
          .matches(/(?=.*[0-9])/, "Password must contain a number.")
          .matches(
            /(?=.*[●!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/,
            "Password must contain a symbol."
          ),
        confirmPassword: Yup.string()
          .required("Enter to confirm password")
          .oneOf([Yup.ref("password"), null], "Password do not match")
      })}
    >
      {props => {
        const {
          values,
          touched,
          errors,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit
        } = props;
        return (
          <>
            <Container component="main" maxWidth="xs">
              <CssBaseline />
              <div className={classes.paper}>
                <Avatar className={classes.avatar}>
                  <LockOutlinedIcon />
                </Avatar>
                <Typography component="h1" variant="h5">
                  Enter Info
                </Typography>
                <form
                  className={classes.form}
                  onSubmit={handleSubmit}
                  noValidate
                >
                  <TextField
                    variant="outlined"
                    margin="normal"
                    required
                    fullWidth
                    id="username"
                    value={values.username}
                    label="username"
                    name="username"
                    autoComplete="username"
                    onChange={e => {
                      setChanged(true);
                      handleChange(e);
                    }}
                    onBlur={handleBlur}
                    className={errors.username && touched.username && "error"}
                  />
                  {errors.username && touched.username && (
                    <div className="input-feedback" style={{ color: "red" }}>
                      {errors.username}
                    </div>
                  )}
                  <TextField
                    variant="outlined"
                    margin="normal"
                    required
                    fullWidth
                    name="password"
                    value={values.password}
                    label="Password"
                    type="password"
                    id="password"
                    onBlur={handleBlur}
                    autoComplete="current-password"
                    className={errors.password && touched.password && "error"}
                    onChange={e => {
                      setChanged(true);
                      handleChange(e);
                    }}
                  />
                  {errors.password && touched.password && (
                    <div className="input-feedback" style={{ color: "red" }}>
                      {errors.password}
                    </div>
                  )}
                  <TextField
                    variant="outlined"
                    margin="normal"
                    required
                    fullWidth
                    name="confirmPassword"
                    value={values.confirmPassword}
                    type="password"
                    label="Confirm Password"
                    id="confirmPassword"
                    onBlur={handleBlur}
                    autoComplete="confirmPassword"
                    className={
                      errors.confirmPassword &&
                      touched.confirmPassword &&
                      "error"
                    }
                    onChange={e => {
                      setChanged(true);
                      handleChange(e);
                    }}
                  />
                  {errors.confirmPassword && touched.confirmPassword && (
                    <div className="input-feedback" style={{ color: "red" }}>
                      {errors.confirmPassword}
                    </div>
                  )}

                  {!changed && loginError && (
                    <div style={{ color: "red" }}>
                      <span>{loginError}</span>
                    </div>
                  )}
                  <Button
                    type="submit"
                    fullWidth
                    variant="contained"
                    color="primary"
                    className={classes.submit}
                    disabled={isSubmitting}
                  >
                    Next
                  </Button>
                </form>
              </div>
              <Box mt={8}>
                <Copyright />
              </Box>
            </Container>
          </>
        );
      }}
    </Formik>
  );
};

export default withRouter(Reg2);

最佳答案

您可以为 register 和 register2 创建一个父组件,并将逻辑存储在要显示的组件中

function MyComponent() {
  const [email, setEmail] = useState(null)

  useEffect(() => {
    (async () => {
      const response = await yourApiCall()
      setEmail(response)
    })()
  }, [])

  return email ? <Register /> : <Register2 />
}

关于javascript - 如何在reactjs中进行内部重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60070181/

相关文章:

javascript - 使用 nodeJS 在 RabbitMQ 中删除消费者

javascript - 使用键的字符串更新 setState

reactjs - 在 React TypeScript 中使用异步等待和 try 和 catch 子句处理 HTTP 错误

javascript - Material ui - 无法使用 makeStyles 覆盖日期选择器样式

reactjs - Material UI Dialog 变成 Hook 闪烁

reactjs - Material UI makeStyles 不会更改所有元素的 css 属性

javascript - 使用 Jquery 显示来自 Ajax 响应的数据

javascript - 动态改变 &lt;textarea > 大小、样式

javascript - 将 javascript Canvas 路径保存到数据库中的正确方法

javascript - 错误 : Cannot set properties of undefined when setting the value of nested object